WIP

^KT-74005
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 0741a19..62fccf0 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -4102,6 +4102,12 @@
             <sha256 value="2933354de8c47ad8216ab32f220aaf5d65f280139921451683bb8b805073c7e3" origin="Generated by Gradle"/>
          </artifact>
       </component>
+      <component group="org.jetbrains.kotlin" name="kotlin-serialization-compiler-plugin-embeddable" version="2.0.20-RC">
+         <artifact name="kotlin-serialization-compiler-plugin-embeddable-2.0.20-RC.jar">
+            <md5 value="94272cc67751384c78c4232bd9407ea2" origin="Generated by Gradle"/>
+            <sha256 value="eaf69310210e6008abaab9de38acfddaebc684b8f312b4f3058808cf20a955c8" origin="Generated by Gradle"/>
+         </artifact>
+      </component>
       <component group="org.jetbrains.kotlin" name="kotlin-serialization-compiler-plugin-embeddable" version="2.2.0-dev-4719">
          <artifact name="kotlin-serialization-compiler-plugin-embeddable-2.2.0-dev-4719.jar">
             <md5 value="8e85fc84ad742f939da2bbc92e70371a" origin="Generated by Gradle"/>
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts
index 6ade092..fba3379 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts
@@ -44,6 +44,7 @@
 val kotlinGradlePluginTest = project(":kotlin-gradle-plugin").sourceSets.named("test").map { it.output }
 
 dependencies {
+    testImplementation(project(":kotlin-gradle-plugin", configuration = "ftConsumable"))
     testImplementation(project(":kotlin-gradle-plugin")) {
         capabilities {
             requireCapability("org.jetbrains.kotlin:kotlin-gradle-plugin-common")
@@ -358,6 +359,11 @@
 
 val mergedTestClassesClasspathTask = tasks.register<Copy>("testClassesCopy") {
     from(kotlin.target.compilations.getByName("test").output.classesDirs)
+    from(
+        configurations.detachedConfiguration(
+            dependencies.create(dependencies.project(":kotlin-gradle-plugin", configuration = "ftConsumable"))
+        )
+    )
     into(layout.buildDirectory.dir("testClassesCopy"))
 }
 
@@ -431,7 +437,9 @@
     val jdk21Provider = project.getToolchainJdkHomeFor(JdkMajorVersion.JDK_21_0)
     val mavenLocalRepo = project.providers.systemProperty("maven.repo.local").orNull
 
-    val mergedTestClassesDirectory = files(mergedTestClassesClasspathTask)
+    val mergedTestClassesDirectory = files(
+        mergedTestClassesClasspathTask,
+    )
     inputs.files(mergedTestClassesDirectory)
     doFirst {
         systemProperty("buildScriptInjectionsClasspath", mergedTestClassesDirectory.single())
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt
index d68dbb2..dd8353b 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PublishingIT.kt
@@ -417,4 +417,4 @@
             assertOutputContains("Variant myConsumableConfiguration")
         }
     }
-}
\ No newline at end of file
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/resources/AndroidMultiplatformResourcesIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/resources/AndroidMultiplatformResourcesIT.kt
index e3128a1..563b260 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/resources/AndroidMultiplatformResourcesIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/resources/AndroidMultiplatformResourcesIT.kt
@@ -31,7 +31,7 @@
             gradleVersion,
             providedJdk,
             androidVersion
-        ).publish(PublisherConfiguration())
+        ).publish(publisherConfiguration = PublisherConfiguration())
 
         val projectDependency = project(
             "multiplatformResources/android/projectDependency",
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/argumentProviders.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/argumentProviders.kt
index 5250043..051b33d 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/argumentProviders.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/argumentProviders.kt
@@ -24,7 +24,7 @@
 @Target(AnnotationTarget.FUNCTION, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.RUNTIME)
 annotation class GradleTestVersions(
-    val minVersion: String = TestVersions.Gradle.MIN_SUPPORTED,
+    val minVersion: String = TestVersions.Gradle.MAX_SUPPORTED,
     val maxVersion: String = TestVersions.Gradle.MAX_SUPPORTED,
     val additionalVersions: Array<String> = [],
 )
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/KmpResolutionIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/KmpResolutionIT.kt
new file mode 100644
index 0000000..9898145
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/KmpResolutionIT.kt
@@ -0,0 +1,950 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.uklibs
+
+import org.gradle.util.GradleVersion
+import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
+import org.jetbrains.kotlin.gradle.testbase.*
+import org.jetbrains.kotlin.gradle.unitTests.uklibs.assertEqualsPP
+import org.junit.jupiter.api.DisplayName
+import org.jetbrains.kotlin.gradle.unitTests.uklibs.compilationResolution
+import org.jetbrains.kotlin.gradle.unitTests.uklibs.ResolvedComponentWithArtifacts
+
+@OptIn(ExperimentalKotlinGradlePluginApi::class)
+@MppGradlePluginTests
+@DisplayName("Test the GMT runtime behavior")
+class KmpResolutionIT : KGPBaseTest() {
+
+    @GradleTest
+    fun `smoke lenient kmp resolution - GMT and platform compilation - direct and transitive are kmp publications`(
+        version: GradleVersion
+    ) {
+        val consumer = transitiveConsumptionCase(
+            version,
+            transitiveConfiguration = {
+                buildScriptInjection {
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                        sourceSets.linuxMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            directConfiguration = {
+                buildScriptInjection {
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                        sourceSets.linuxMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            consumerConfiguration = {
+                buildScriptInjection {
+                    project.setUklibResolutionStrategy()
+                }
+            }
+        )
+
+        assertEqualsPP(
+            listOf(
+                listOf("commonMain", "org.jetbrains.kotlin-kotlin-stdlib-${consumer.buildOptions.kotlinVersion}-commonMain-.klib"),
+                listOf("commonMain", "foo-transitive-1.0-commonMain-.klib"),
+            ),
+            consumer.metadataTransformationOutputClasspath("commonMain")
+                .relativeTransformationPathComponents(),
+        )
+        assertEqualsPP(
+            listOf(
+                listOf("linuxMain", "foo-direct-1.0-linuxMain-.klib"),
+                listOf("linuxMain", "foo-direct-1.0-commonMain-.klib"),
+                listOf("linuxMain", "foo-transitive-1.0-linuxMain-.klib"),
+                listOf("commonMain", "org.jetbrains.kotlin-kotlin-stdlib-${consumer.buildOptions.kotlinVersion}-commonMain-.klib"),
+                listOf("commonMain", "foo-transitive-1.0-commonMain-.klib"),
+            ),
+            consumer.metadataTransformationOutputClasspath("linuxMain")
+                .relativeTransformationPathComponents(),
+        )
+
+        val jvmDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.jvm().compilationResolution()
+            }
+        }.buildAndReturn()
+        val iosDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.iosArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+        val linuxDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.linuxArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "metadataApiElements",
+                ),
+                "foo:transitive-jvm:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "standard-jvm",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                            "org.jetbrains.kotlin.platform.type" to "jvm",
+                        ),
+                    ),
+                    configuration = "jvmApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "jvmApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "standard-jvm",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "integration",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                            "org.jetbrains.kotlin.platform.type" to "jvm",
+                        ),
+                    ),
+                    configuration = "jvmApiElements",
+                ),
+                "org.jetbrains:annotations:13.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                        ),
+                    ),
+                    configuration = "compile",
+                ),
+            ),
+            jvmDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        // metadata jar is filtered
+                    ),
+                    configuration = "metadataApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        // This is a stub in stdlib publication for native
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+                "foo:transitive-iosarm64:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "org.jetbrains.kotlin.klib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "non-jvm",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-api",
+                            "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+                            "org.jetbrains.kotlin.native.target" to "ios_arm64",
+                            "org.jetbrains.kotlin.platform.type" to "native",
+                        ),
+                    ),
+                    configuration = "iosArm64ApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "iosArm64ApiElements-published",
+                ),
+            ),
+            iosDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct-linuxarm64:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "org.jetbrains.kotlin.klib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "non-jvm",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-api",
+                            "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+                            "org.jetbrains.kotlin.native.target" to "linux_arm64",
+                            "org.jetbrains.kotlin.platform.type" to "native",
+                        ),
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "foo:transitive-linuxarm64:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "org.jetbrains.kotlin.klib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "non-jvm",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-api",
+                            "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+                            "org.jetbrains.kotlin.native.target" to "linux_arm64",
+                            "org.jetbrains.kotlin.platform.type" to "native",
+                        ),
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            linuxDependencies,
+        )
+    }
+
+    @GradleTest
+    fun `smoke lenient kmp resolution - GMT and platform compilation - with direct uklib producer`(
+        version: GradleVersion
+    ) {
+        val consumer = transitiveConsumptionCase(
+            version,
+            transitiveConfiguration = {
+                buildScriptInjection {
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                        sourceSets.linuxMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            directConfiguration = {
+                buildScriptInjection {
+                    project.enableUklibPublication()
+                    project.applyMultiplatform {
+                        // Now it can't have linuxMain due to bamboos
+                        sourceSets.commonMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            consumerConfiguration = {
+                buildScriptInjection {
+                    project.setUklibResolutionStrategy()
+                }
+            }
+        )
+
+        assertEqualsPP(
+            mutableListOf(
+                mutableListOf(
+                    "commonMain", "org.jetbrains.kotlin-kotlin-stdlib-2.2.255-SNAPSHOT-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "foo-transitive-1.0-commonMain-.klib",
+                ),
+            ),
+            consumer.metadataTransformationOutputClasspath("commonMain")
+                .relativeTransformationPathComponents(),
+        )
+        assertEqualsPP(
+            mutableListOf(
+                mutableListOf(
+                    "linuxMain", "uklib-foo-direct-1.0-commonMain-",
+                ),
+                mutableListOf(
+                    "linuxMain", "foo-transitive-1.0-linuxMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "org.jetbrains.kotlin-kotlin-stdlib-2.2.255-SNAPSHOT-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "foo-transitive-1.0-commonMain-.klib",
+                ),
+            ),
+            consumer.metadataTransformationOutputClasspath("linuxMain")
+                .relativeTransformationPathComponents(),
+        )
+
+        val jvmDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.jvm().compilationResolution()
+            }
+        }.buildAndReturn()
+        val iosDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.iosArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+        val linuxDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.linuxArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        // Ignored because it doesn't have a jvm target
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "foo:transitive-jvm:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "standard-jvm",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                            "org.jetbrains.kotlin.platform.type" to "jvm",
+                        ),
+                    ),
+                    configuration = "jvmApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "jvmApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "standard-jvm",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "integration",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                            "org.jetbrains.kotlin.platform.type" to "jvm",
+                        ),
+                    ),
+                    configuration = "jvmApiElements",
+                ),
+                "org.jetbrains:annotations:13.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                        ),
+                    ),
+                    configuration = "compile",
+                ),
+            ),
+            jvmDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        // Ignored because it doesn't have an iOS target
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "foo:transitive-iosarm64:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "org.jetbrains.kotlin.klib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "non-jvm",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-api",
+                            "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+                            "org.jetbrains.kotlin.native.target" to "ios_arm64",
+                            "org.jetbrains.kotlin.platform.type" to "native",
+                        ),
+                    ),
+                    configuration = "iosArm64ApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "iosArm64ApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            iosDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "linux_arm64",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "foo:transitive-linuxarm64:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "org.jetbrains.kotlin.klib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "non-jvm",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-api",
+                            "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+                            "org.jetbrains.kotlin.native.target" to "linux_arm64",
+                            "org.jetbrains.kotlin.platform.type" to "native",
+                        ),
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            linuxDependencies,
+        )
+    }
+
+    @GradleTest
+    fun `smoke lenient kmp resolution - GMT and platform compilation - with direct and transitive uklib producer`(
+        version: GradleVersion
+    ) {
+        val consumer = transitiveConsumptionCase(
+            version,
+            transitiveConfiguration = {
+                // transitive is regular KMP producer
+                buildScriptInjection {
+                    project.enableUklibPublication()
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                        sourceSets.linuxMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            directConfiguration = {
+                // direct is Uklib producer
+                buildScriptInjection {
+                    project.enableUklibPublication()
+                    project.setUklibResolutionStrategy()
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            consumerConfiguration = {
+                // consumer can resolve Uklibs
+                buildScriptInjection {
+                    project.setUklibResolutionStrategy()
+                }
+            }
+        )
+
+        assertEqualsPP(
+            mutableListOf(
+                mutableListOf(
+                    "commonMain", "org.jetbrains.kotlin-kotlin-stdlib-2.2.255-SNAPSHOT-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "uklib-foo-transitive-1.0-commonMain-",
+                ),
+            ),
+            consumer.metadataTransformationOutputClasspath("commonMain")
+                .relativeTransformationPathComponents(),
+        )
+        assertEqualsPP(
+            mutableListOf(
+                mutableListOf(
+                    "linuxMain", "uklib-foo-direct-1.0-commonMain-",
+                ),
+                mutableListOf(
+                    "linuxMain", "uklib-foo-transitive-1.0-linuxMain-",
+                ),
+                mutableListOf(
+                    "commonMain", "org.jetbrains.kotlin-kotlin-stdlib-2.2.255-SNAPSHOT-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "uklib-foo-transitive-1.0-commonMain-",
+                ),
+            ),
+            consumer.metadataTransformationOutputClasspath("linuxMain")
+                .relativeTransformationPathComponents(),
+        )
+
+        val jvmDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.jvm().compilationResolution()
+            }
+        }.buildAndReturn()
+        val iosDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.iosArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+        val linuxDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.linuxArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "jvm",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-dom-api-compat:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "commonFakeApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "standard-jvm",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "integration",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                            "org.jetbrains.kotlin.platform.type" to "jvm",
+                        ),
+                    ),
+                    configuration = "jvmApiElements",
+                ),
+                "org.jetbrains:annotations:13.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                        ),
+                    ),
+                    configuration = "compile",
+                ),
+            ),
+            jvmDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "ios_arm64",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-dom-api-compat:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "commonFakeApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            iosDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "linux_arm64",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "linux_arm64",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-dom-api-compat:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "commonFakeApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            linuxDependencies,
+        )
+    }
+
+    @GradleTest
+    fun `smoke lenient kmp resolution - GMT and platform compilation - with transitive uklib producer through direct kmp dependency`(
+        version: GradleVersion
+    ) {
+        val consumer = transitiveConsumptionCase(
+            version,
+            transitiveConfiguration = {
+                buildScriptInjection {
+                    project.enableUklibPublication()
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                        sourceSets.linuxMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            directConfiguration = {
+                buildScriptInjection {
+                    project.setUklibResolutionStrategy()
+                    project.applyMultiplatform {
+                        sourceSets.commonMain.get().addIdentifierClass()
+                        sourceSets.linuxMain.get().addIdentifierClass()
+                    }
+                }
+            },
+            consumerConfiguration = {
+                buildScriptInjection {
+                    project.setUklibResolutionStrategy()
+                }
+            }
+        )
+
+        assertEqualsPP(
+            mutableListOf(
+                mutableListOf(
+                    "commonMain", "org.jetbrains.kotlin-kotlin-stdlib-2.2.255-SNAPSHOT-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "uklib-foo-transitive-1.0-commonMain-",
+                ),
+            ),
+            consumer.metadataTransformationOutputClasspath("commonMain")
+                .relativeTransformationPathComponents(),
+        )
+        assertEqualsPP(
+            mutableListOf(
+                mutableListOf(
+                    "linuxMain", "foo-direct-1.0-linuxMain-.klib",
+                ),
+                mutableListOf(
+                    "linuxMain", "foo-direct-1.0-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "linuxMain", "uklib-foo-transitive-1.0-linuxMain-",
+                ),
+                mutableListOf(
+                    "commonMain", "org.jetbrains.kotlin-kotlin-stdlib-2.2.255-SNAPSHOT-commonMain-.klib",
+                ),
+                mutableListOf(
+                    "commonMain", "uklib-foo-transitive-1.0-commonMain-",
+                ),
+            ),
+            consumer.metadataTransformationOutputClasspath("linuxMain")
+                .relativeTransformationPathComponents(),
+        )
+
+        val jvmDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.jvm().compilationResolution()
+            }
+        }.buildAndReturn()
+        val iosDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.iosArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+        val linuxDependencies = consumer.buildScriptReturn {
+            project.ignoreAccessViolations {
+                kotlinMultiplatform.linuxArm64().compilationResolution()
+            }
+        }.buildAndReturn()
+
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "metadataApiElements",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "jvm",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-dom-api-compat:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "commonFakeApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "standard-jvm",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "integration",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                            "org.jetbrains.kotlin.platform.type" to "jvm",
+                        ),
+                    ),
+                    configuration = "jvmApiElements",
+                ),
+                "org.jetbrains:annotations:13.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "jar",
+                            "org.gradle.category" to "library",
+                            "org.gradle.libraryelements" to "jar",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "java-api",
+                            "org.jetbrains.kotlin.isMetadataJar" to "non-a-metadata-jar",
+                        ),
+                    ),
+                    configuration = "compile",
+                ),
+            ),
+            jvmDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "metadataApiElements",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "ios_arm64",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-dom-api-compat:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "commonFakeApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            iosDependencies,
+        )
+        assertEqualsPP(
+            mutableMapOf(
+                "foo:direct-linuxarm64:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "org.jetbrains.kotlin.klib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.jvm.environment" to "non-jvm",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-api",
+                            "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+                            "org.jetbrains.kotlin.native.target" to "linux_arm64",
+                            "org.jetbrains.kotlin.platform.type" to "native",
+                        ),
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "foo:direct:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "linuxArm64ApiElements-published",
+                ),
+                "foo:transitive:1.0" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                        mutableMapOf(
+                            "artifactType" to "uklib",
+                            "org.gradle.category" to "library",
+                            "org.gradle.status" to "release",
+                            "org.gradle.usage" to "kotlin-uklib-api",
+                            "org.jetbrains.kotlin.uklibState" to "decompressed",
+                            "org.jetbrains.kotlin.uklibView" to "linux_arm64",
+                        ),
+                    ),
+                    configuration = "uklibApiElements",
+                ),
+                "org.jetbrains.kotlin:kotlin-dom-api-compat:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "commonFakeApiElements-published",
+                ),
+                "org.jetbrains.kotlin:kotlin-stdlib:2.2.255-SNAPSHOT" to ResolvedComponentWithArtifacts(
+                    artifacts = mutableListOf(
+                    ),
+                    configuration = "nativeApiElements",
+                ),
+            ),
+            linuxDependencies,
+        )
+    }
+
+    private fun transitiveConsumptionCase(
+        gradleVersion: GradleVersion,
+        transitiveConfiguration: TestProject.() -> Unit,
+        directConfiguration: TestProject.() -> Unit,
+        consumerConfiguration: TestProject.() -> Unit,
+    ): TestProject {
+        val transitiveProducer = project("empty", gradleVersion) {
+            settingsBuildScriptInjection {
+                settings.rootProject.name = "transitive"
+            }
+            addKgpToBuildScriptCompilationClasspath()
+            transitiveConfiguration()
+            buildScriptInjection {
+                project.applyMultiplatform {
+                    js()
+                    jvm()
+                    iosArm64()
+                    iosX64()
+                    linuxArm64()
+                    linuxX64()
+                }
+            }
+        }.publish(publisherConfiguration = PublisherConfiguration(group = "foo"))
+
+        val directProducer = project("empty", gradleVersion) {
+            settingsBuildScriptInjection {
+                settings.rootProject.name = "direct"
+            }
+            addKgpToBuildScriptCompilationClasspath()
+            addPublishedProjectToRepositories(transitiveProducer)
+            directConfiguration()
+            buildScriptInjection {
+                project.applyMultiplatform {
+                    linuxArm64()
+                    linuxX64()
+
+                    sourceSets.commonMain.get().dependencies {
+                        api(transitiveProducer.rootCoordinate)
+                    }
+                }
+            }
+        }.publish(publisherConfiguration = PublisherConfiguration(group = "foo"))
+
+        return project("empty", gradleVersion) {
+            settingsBuildScriptInjection {
+                settings.rootProject.name = "consumer"
+            }
+            addKgpToBuildScriptCompilationClasspath()
+            addPublishedProjectToRepositories(directProducer)
+            addPublishedProjectToRepositories(transitiveProducer)
+            consumerConfiguration()
+            buildScriptInjection {
+                project.applyMultiplatform {
+                    js()
+                    jvm()
+                    iosArm64()
+                    iosX64()
+                    linuxArm64()
+                    linuxX64()
+
+                    sourceSets.commonMain.get().dependencies {
+                        implementation(directProducer.rootCoordinate)
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionGranularMetadataTransformationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionGranularMetadataTransformationIT.kt
index 11ad72d..de1e3e1 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionGranularMetadataTransformationIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionGranularMetadataTransformationIT.kt
@@ -8,12 +8,8 @@
 import org.gradle.util.GradleVersion
 import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
-import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
-import org.jetbrains.kotlin.gradle.plugin.mpp.locateOrRegisterMetadataDependencyTransformationTask
 import org.jetbrains.kotlin.gradle.testbase.*
 import org.junit.jupiter.api.DisplayName
-import java.io.File
-import kotlin.io.path.pathString
 import kotlin.test.assertEquals
 
 @OptIn(ExperimentalKotlinGradlePluginApi::class)
@@ -96,7 +92,6 @@
             addPublishedProjectToRepositoriesAndIgnoreGradleMetadata(transitivePublisher)
             buildScriptInjection {
                 project.setUklibResolutionStrategy()
-                project.computeUklibChecksum(false)
                 project.applyMultiplatform {
                     iosArm64()
                     iosX64()
@@ -201,7 +196,7 @@
             addKgpToBuildScriptCompilationClasspath()
             addPublishedProjectToRepositoriesAndIgnoreGradleMetadata(publishedProject)
             buildScriptInjection {
-                project.computeUklibChecksum(false)
+                project.computeTransformedLibraryChecksum(false)
                 project.enableCrossCompilation()
                 project.setUklibResolutionStrategy()
                 project.applyMultiplatform {
@@ -231,27 +226,6 @@
         }
     }
 
-    // Take full paths of the classpath formed by the GMT and extract last 2 path components for assertions
-    private fun List<File>.relativeTransformationPathComponents(): List<List<String>> = map { it.lastPathComponents(2) }
-    private fun File.lastPathComponents(number: Int): List<String> = toPath().toList().takeLast(number).map { it.pathString }
-
-    private fun TestProject.metadataTransformationOutputClasspath(
-        sourceSetName: String,
-    ): List<File> {
-        val iosMainTransformationTask = buildScriptReturn {
-            project.locateOrRegisterMetadataDependencyTransformationTask(
-                kotlinMultiplatform.sourceSets.getByName(sourceSetName)
-            ).name
-        }.buildAndReturn()
-        val outputClasspath = buildScriptReturn {
-            val transformationTask = project.locateOrRegisterMetadataDependencyTransformationTask(
-                kotlinMultiplatform.sourceSets.getByName(sourceSetName)
-            ).get()
-            transformationTask.allTransformedLibraries().get()
-        }.buildAndReturn(iosMainTransformationTask)
-        return outputClasspath
-    }
-
     private fun publishUklib(
         gradleVersion: GradleVersion,
         publisherConfiguration: PublisherConfiguration,
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionIT.kt
index 2e67fbe..0ea1a0b 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibConsumptionIT.kt
@@ -40,9 +40,9 @@
             iosX64()
             macosArm64()
             jvm()
-            js()
-            wasmJs()
-            wasmWasi()
+//            js()
+//            wasmJs()
+//            wasmWasi()
         }
         val publisher = publishUklib(gradleVersion, androidVersion) {
             project.plugins.apply("com.android.library")
@@ -425,7 +425,7 @@
             addPublishedProjectToRepositoriesAndIgnoreGradleMetadata(direct)
             addPublishedProjectToRepositoriesAndIgnoreGradleMetadata(transitive)
             buildScriptInjection {
-                project.computeUklibChecksum(false)
+                project.computeTransformedLibraryChecksum(false)
                 project.setUklibResolutionStrategy()
                 project.applyMultiplatform {
                     linuxArm64()
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationIT.kt
index 3f576b1..b57a8b8 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationIT.kt
@@ -498,6 +498,45 @@
         )
     }
 
+    @GradleTest
+    fun `uklib publication layout - we only output 1 component with Gradle metadata with appropriate number of variants`(
+        gradleVersion: GradleVersion,
+    ) {
+        val producer = publishUklib(
+            gradleVersion = gradleVersion,
+        ) {
+            jvm()
+//            iosX64()
+//            iosArm64()
+            sourceSets.commonMain.get().compileSource("class Common")
+        }.publishedProject
+
+        // FIXME: Finish metadata validations
+        val f = producer.rootComponent.gradleMetadata
+        println(f)
+    }
+
+    @GradleTest
+    fun `current kmp publication layout`(
+        gradleVersion: GradleVersion,
+    ) {
+        val producer = project(
+            "empty",
+            gradleVersion = gradleVersion,
+        ) {
+            addKgpToBuildScriptCompilationClasspath()
+            buildScriptInjection {
+                project.applyMultiplatform {
+                    jvm()
+                    sourceSets.commonMain.get().compileSource("class Common")
+                }
+            }
+        }.publish()
+
+        val f = producer.rootComponent.gradleMetadata
+        println(f)
+    }
+
     @kotlinx.serialization.Serializable
     data class Fragment(
         val identifier: String,
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationITWIP.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationITWIP.kt
new file mode 100644
index 0000000..a004176
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/UklibPublicationITWIP.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.uklibs
+
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.decodeFromStream
+import org.gradle.util.GradleVersion
+import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
+import org.jetbrains.kotlin.gradle.mpp.resources.unzip
+import org.jetbrains.kotlin.gradle.testbase.*
+import org.junit.jupiter.api.DisplayName
+import java.io.FileInputStream
+import java.io.Serializable
+import java.nio.file.Path
+import kotlin.io.path.createDirectory
+import kotlin.io.path.listDirectoryEntries
+import kotlin.io.path.name
+import kotlin.test.assertEquals
+import com.android.build.api.dsl.LibraryExtension
+import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication.ArchiveUklibTask
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.Uklib
+import org.w3c.dom.Document
+import org.w3c.dom.Element
+import java.io.File
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.diagnostics.UklibFragmentsChecker
+
+@ExperimentalKotlinGradlePluginApi
+@MppGradlePluginTests
+@DisplayName("Smoke test uklib artifact publication")
+class UklibPublicationITWIP : KGPBaseTest() {
+
+    @GradleTest
+    fun `test`(
+        gradleVersion: GradleVersion,
+    ) {
+        val res = project("empty", gradleVersion) {
+            addKgpToBuildScriptCompilationClasspath()
+            buildScriptInjection {
+                project.applyMultiplatform {
+                    iosArm64()
+                    iosX64()
+                    macosArm64()
+                    macosX64()
+                    // sourceSets.macosMain.get().compileSource("expect fun foo()")
+                    applyHierarchyTemplate {
+                        group("a") {
+                            withIosArm64()
+                            withIosX64()
+                        }
+                        group("b") {
+                            withMacosArm64()
+                            withMacosX64()
+                        }
+                    }
+                }
+            }
+        }.publish(publisherConfiguration = PublisherConfiguration(group = "transitive"))
+        println(res)
+    }
+
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/resolutionTesting.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/resolutionTesting.kt
new file mode 100644
index 0000000..fafbc24
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/resolutionTesting.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.uklibs
+
+import org.gradle.api.Project
+import org.gradle.api.internal.GradleInternal
+import org.gradle.api.internal.project.ProjectStateRegistry
+import org.jetbrains.kotlin.gradle.plugin.mpp.locateOrRegisterMetadataDependencyTransformationTask
+import org.jetbrains.kotlin.gradle.testbase.TestProject
+import org.jetbrains.kotlin.gradle.testbase.buildScriptReturn
+import java.io.File
+import kotlin.io.path.pathString
+
+fun <T> Project.ignoreAccessViolations(code: () -> (T)) = (project.gradle as GradleInternal).services.get(
+    ProjectStateRegistry::class.java).allowUncontrolledAccessToAnyProject { code() }
+
+fun TestProject.metadataTransformationOutputClasspath(
+    sourceSetName: String,
+): List<File> {
+    val iosMainTransformationTask = buildScriptReturn {
+        project.locateOrRegisterMetadataDependencyTransformationTask(
+            kotlinMultiplatform.sourceSets.getByName(sourceSetName)
+        ).name
+    }.buildAndReturn()
+    val outputClasspath = buildScriptReturn {
+        val transformationTask = project.locateOrRegisterMetadataDependencyTransformationTask(
+            kotlinMultiplatform.sourceSets.getByName(sourceSetName)
+        ).get()
+        transformationTask.allTransformedLibraries().get()
+    }.buildAndReturn(iosMainTransformationTask)
+    return outputClasspath
+}
+
+fun List<File>.relativeTransformationPathComponents(): List<List<String>> = map { it.lastPathComponents(2) }
+private fun File.lastPathComponents(number: Int): List<String> = toPath().toList().takeLast(number).map { it.pathString }
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/uklibTestingUtils.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/uklibTestingUtils.kt
index c2b6c98..de977f1 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/uklibTestingUtils.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/uklibs/uklibTestingUtils.kt
@@ -14,8 +14,7 @@
 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
 import org.jetbrains.kotlin.gradle.internal.properties.nativeProperties
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
-import org.jetbrains.kotlin.gradle.plugin.extraProperties
-import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.UklibResolutionStrategy
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.KmpResolutionStrategy
 import org.jetbrains.kotlin.gradle.testbase.*
 import org.jetbrains.kotlin.internal.compilerRunner.native.nativeCompilerClasspath
 import java.io.File
@@ -60,6 +59,7 @@
         val uklib: File get() = path.resolve("${artifactsPrefix}.uklib")
         val jar: File get() = path.resolve("${artifactsPrefix}.jar")
         val psmJar: File get() = path.resolve("${artifactsPrefix}-psm.jar")
+        val gradleMetadata: File get() = path.resolve("${artifactsPrefix}.module")
     }
 
     val rootCoordinate: String = "$group:$name:$version"
@@ -273,16 +273,17 @@
     )
 }
 
-internal fun Project.setUklibResolutionStrategy(strategy: UklibResolutionStrategy = UklibResolutionStrategy.ResolveUklibsInMavenComponents) {
+internal fun Project.setUklibResolutionStrategy(strategy: KmpResolutionStrategy = KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently) {
     propertiesExtension.set(
-        PropertiesProvider.PropertyNames.KOTLIN_KMP_UKLIB_RESOLUTION_STRATEGY,
+        PropertiesProvider.PropertyNames.KOTLIN_KMP_RESOLUTION_STRATEGY,
         strategy.propertyName,
     )
+    computeTransformedLibraryChecksum(false)
 }
 
-fun Project.computeUklibChecksum(enable: Boolean = false) {
+fun Project.computeTransformedLibraryChecksum(enable: Boolean = false) {
     propertiesExtension.set(
-        PropertiesProvider.PropertyNames.KOTLIN_MPP_COMPUTE_UKLIB_CHECKSUM,
+        PropertiesProvider.PropertyNames.KOTLIN_MPP_COMPUTE_TRANSFORMED_LIBRARY_CHECKSUM,
         enable.toString(),
     )
 }
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/compilerArgumentUtils.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/itCompilerArgumentUtils.kt
similarity index 100%
rename from libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/compilerArgumentUtils.kt
rename to libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/itCompilerArgumentUtils.kt
diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts
index 7b76e34..c7a9bd0 100644
--- a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts
+++ b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts
@@ -201,6 +201,7 @@
     testImplementation(project(":kotlin-gradle-statistics"))
     testImplementation(project(":kotlin-tooling-metadata"))
     testImplementation(libs.lincheck)
+    testImplementation(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false }
 }
 
 configurations.commonCompileClasspath.get().exclude("org.jetbrains.kotlinx", "kotlinx-coroutines-core")
@@ -346,58 +347,58 @@
              */
             pivotVersion = KotlinMetadataPivotVersion(1, 8, 0)
         }
-        asmDeprecation {
-            val exclusions = listOf(
-                "org.jetbrains.kotlin.gradle.**", // part of the plugin
-                "org.jetbrains.kotlin.project.model.**", // part of the plugin
-                "org.jetbrains.kotlin.statistics.**", // part of the plugin
-                "org.jetbrains.kotlin.tooling.**", // part of the plugin
-                "org.jetbrains.kotlin.org.**", // already shadowed dependencies
-                "org.jetbrains.kotlin.com.**", // already shadowed dependencies
-                "org.jetbrains.kotlin.it.unimi.**", // already shadowed dependencies
-                "org.jetbrains.kotlin.internal.**", // already internal package
-            )
-            val deprecationMessage = """
-                You're using a Kotlin compiler class bundled into KGP for its internal needs.
-                This is discouraged and will not be supported in future releases.
-                The class in this artifact is scheduled for removal in Kotlin 2.2. Please define dependency on it in an alternative way.
-                See https://kotl.in/gradle/internal-compiler-symbols for more details
-            """.trimIndent()
-            deprecateClassesByPattern("org.jetbrains.kotlin.**", deprecationMessage, exclusions)
-        }
+//        asmDeprecation {
+//            val exclusions = listOf(
+//                "org.jetbrains.kotlin.gradle.**", // part of the plugin
+//                "org.jetbrains.kotlin.project.model.**", // part of the plugin
+//                "org.jetbrains.kotlin.statistics.**", // part of the plugin
+//                "org.jetbrains.kotlin.tooling.**", // part of the plugin
+//                "org.jetbrains.kotlin.org.**", // already shadowed dependencies
+//                "org.jetbrains.kotlin.com.**", // already shadowed dependencies
+//                "org.jetbrains.kotlin.it.unimi.**", // already shadowed dependencies
+//                "org.jetbrains.kotlin.internal.**", // already internal package
+//            )
+//            val deprecationMessage = """
+//                You're using a Kotlin compiler class bundled into KGP for its internal needs.
+//                This is discouraged and will not be supported in future releases.
+//                The class in this artifact is scheduled for removal in Kotlin 2.2. Please define dependency on it in an alternative way.
+//                See https://kotl.in/gradle/internal-compiler-symbols for more details
+//            """.trimIndent()
+//            deprecateClassesByPattern("org.jetbrains.kotlin.**", deprecationMessage, exclusions)
+//        }
     }
-    GradlePluginVariant.values().forEach { variant ->
-        if (kotlinBuildProperties.isInJpsBuildIdeaSync) return@forEach
-        val sourceSet = sourceSets.getByName(variant.sourceSetName)
-        val taskSuffix = sourceSet.jarTaskName.capitalize()
-        val shadowJarTaskName = "$EMBEDDABLE_COMPILER_TASK_NAME$taskSuffix"
-        asmDeprecation {
-            val dumpTask = registerDumpDeprecationsTask(shadowJarTaskName, taskSuffix)
-            val dumpAllTask = getOrCreateTask<Task>("dumpDeprecations") {
-                dependsOn(dumpTask)
-            }
-            val expectedFileDoesNotExistMessage = """
-                The file with expected deprecations for the compiler modules bundled into KGP does not exist.
-                Run ./gradlew ${project.path}:${dumpTask.name} first to create it.
-                You may also use ./gradlew ${project.path}:${dumpAllTask.name} to dump deprecations of all fat jars.
-                Context: https://youtrack.jetbrains.com/issue/KT-70251
-            """.trimIndent()
-            val checkFailureMessage = """
-                Expected deprecations applied to the compiler modules bundled into KGP does not match with the actually applied ones.
-                Run ./gradlew ${project.path}:${dumpTask.name} to see the difference.
-                You may also use ./gradlew ${project.path}:${dumpAllTask.name} to dump deprecations of all fat jars.
-                Use INFO level log for the exact deprecated classes set.
-                Either commit the difference or adjust the package relocation rules in ${buildFile.absolutePath}
-                Please be sure to leave a comment explaining any changes related to this failure clear enough.
-                Context: https://youtrack.jetbrains.com/issue/KT-70251
-            """.trimIndent()
-            val checkTask =
-                registerCheckDeprecationsTask(shadowJarTaskName, taskSuffix, expectedFileDoesNotExistMessage, checkFailureMessage)
-            named("check") {
-                dependsOn(checkTask)
-            }
-        }
-    }
+//    GradlePluginVariant.values().forEach {
+//        if (kotlinBuildProperties.isInJpsBuildIdeaSync) return@forEach
+//        val sourceSet = sourceSets.getByName(variant.sourceSetName)
+//        val taskSuffix = sourceSet.jarTaskName.capitalize()
+//        val shadowJarTaskName = "$EMBEDDABLE_COMPILER_TASK_NAME$taskSuffix"
+//        asmDeprecation {
+//            val dumpTask = registerDumpDeprecationsTask(shadowJarTaskName, taskSuffix)
+//            val dumpAllTask = getOrCreateTask<Task>("dumpDeprecations") {
+//                dependsOn(dumpTask)
+//            }
+//            val expectedFileDoesNotExistMessage = """
+//                The file with expected deprecations for the compiler modules bundled into KGP does not exist.
+//                Run ./gradlew ${project.path}:${dumpTask.name} first to create it.
+//                You may also use ./gradlew ${project.path}:${dumpAllTask.name} to dump deprecations of all fat jars.
+//                Context: https://youtrack.jetbrains.com/issue/KT-70251
+//            """.trimIndent()
+//            val checkFailureMessage = """
+//                Expected deprecations applied to the compiler modules bundled into KGP does not match with the actually applied ones.
+//                Run ./gradlew ${project.path}:${dumpTask.name} to see the difference.
+//                You may also use ./gradlew ${project.path}:${dumpAllTask.name} to dump deprecations of all fat jars.
+//                Use INFO level log for the exact deprecated classes set.
+//                Either commit the difference or adjust the package relocation rules in ${buildFile.absolutePath}
+//                Please be sure to leave a comment explaining any changes related to this failure clear enough.
+//                Context: https://youtrack.jetbrains.com/issue/KT-70251
+//            """.trimIndent()
+//            val checkTask =
+//                registerCheckDeprecationsTask(shadowJarTaskName, taskSuffix, expectedFileDoesNotExistMessage, checkFailureMessage)
+//            named("check") {
+//                dependsOn(checkTask)
+//            }
+//        }
+//    }
 }
 
 tasks.named("validatePlugins") {
@@ -488,7 +489,17 @@
         }
     }
 
+    val ftConsumable = configurations.create("ftConsumable") {
+        isCanBeConsumed = true
+        isCanBeResolved = false
+    }
     val functionalTestCompilation = kotlin.target.compilations.getByName("functionalTest")
+    functionalTestCompilation.output.classesDirs.forEach {
+        ftConsumable.outgoing.artifact(it) {
+            builtBy(functionalTestCompilation.compileTaskProvider)
+        }
+    }
+
     functionalTestCompilation.compileJavaTaskProvider.configure {
         sourceCompatibility = JavaLanguageVersion.of(17).toString()
         targetCompatibility = JavaLanguageVersion.of(17).toString()
@@ -498,6 +509,10 @@
             kotlinJavaToolchain.toolchain.use(project.getToolchainLauncherFor(JdkMajorVersion.JDK_17_0))
         }
     }
+    functionalTestCompilation.configurations.pluginConfiguration.dependencies.add(
+        // FIXME: Do we intentionally use different kotlin versions with BTA impl and without? Or how does this even work?
+        dependencies.create("org.jetbrains.kotlin:kotlin-serialization-compiler-plugin-embeddable:${libs.versions.kotlin.`for`.gradle.plugins.compilation.get()}")
+    )
     functionalTestCompilation.associateWith(kotlin.target.compilations.getByName(gradlePluginVariantForFunctionalTests.sourceSetName))
     functionalTestCompilation.associateWith(kotlin.target.compilations.getByName("common"))
 
@@ -562,10 +577,11 @@
         }
         implementation("org.reflections:reflections:0.10.2")
         implementation(project(":compose-compiler-gradle-plugin"))
+        implementation(libs.kotlinx.serialization.json)
     }
 
     tasks.named("check") {
         dependsOn("functionalTest")
         dependsOn("lincheckTest")
     }
-}
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt
index 0140d41..b35004e 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt
@@ -136,7 +136,7 @@
                 val stdlibModule = compilation.platformType.stdlibPlatformType(this, kotlinSourceSet, stdlibVersion >= kotlin1920Version)
                     ?: return@withDependencies
 
-                KotlinStdlibConfigurationMetrics.collectMetrics(project, requestedStdlibVersion)
+//                KotlinStdlibConfigurationMetrics.collectMetrics(project, requestedStdlibVersion)
 
                 dependencySet.addLater(
                     coreLibrariesVersion.map {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt
index 37bbceb..4b8879d 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt
@@ -10,7 +10,7 @@
 import org.gradle.api.provider.Provider
 import org.gradle.util.GradleVersion
 import org.jetbrains.kotlin.compilerRunner.KotlinCompilerArgumentsLogLevel
-import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.UklibResolutionStrategy
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.KmpResolutionStrategy
 import org.jetbrains.kotlin.gradle.dsl.NativeCacheOrchestration
 import org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode
 import org.jetbrains.kotlin.gradle.internal.properties.PropertiesBuildService
@@ -35,7 +35,7 @@
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_APPLY_DEFAULT_HIERARCHY_TEMPLATE
-import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_COMPUTE_UKLIB_CHECKSUM
+import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_COMPUTE_TRANSFORMED_LIBRARY_CHECKSUM
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_INTRANSITIVE_METADATA_CONFIGURATION
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_OPTIMISTIC_NUMBER_COMMONIZATION
@@ -47,7 +47,7 @@
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_IMPORT_ENABLE_SLOW_SOURCES_JAR_RESOLVER
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_RESOURCES_RESOLUTION_STRATEGY
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_FAKE_UKLIB_TRANSFORMS
-import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_KMP_UKLIB_RESOLUTION_STRATEGY
+import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_KMP_RESOLUTION_STRATEGY
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_SUPPRESS_EXPERIMENTAL_ARTIFACTS_DSL_WARNING
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE
@@ -187,18 +187,18 @@
     val publishUklib: Boolean
         get() = booleanProperty(KOTLIN_MPP_PUBLISH_UKLIB) ?: false
 
-    val uklibResolutionStrategy: UklibResolutionStrategy
-        get() = this.get(KOTLIN_KMP_UKLIB_RESOLUTION_STRATEGY)?.let {
-            UklibResolutionStrategy.fromProperty(it)
-        } ?: UklibResolutionStrategy.IgnoreUklibs
+    val kmpResolutionStrategy: KmpResolutionStrategy
+        get() = this.get(KOTLIN_KMP_RESOLUTION_STRATEGY)?.let {
+            KmpResolutionStrategy.fromProperty(it)
+        } ?: KmpResolutionStrategy.StandardKMPResolution
 
     // This property makes transforms noop and is used in functionalTest resolution tests
     val fakeUkibTransforms: Boolean
         get() = booleanProperty(KOTLIN_MPP_FAKE_UKLIB_TRANSFORMS) ?: false
 
     // This property disables -${checksum} output path suffix in the GMT transformed output klib to make them testable
-    val computeUklibChecksum: Boolean
-        get() = booleanProperty(KOTLIN_MPP_COMPUTE_UKLIB_CHECKSUM) ?: true
+    val computeTransformedLibraryChecksum: Boolean
+        get() = booleanProperty(KOTLIN_MPP_COMPUTE_TRANSFORMED_LIBRARY_CHECKSUM) ?: true
 
     val enableKotlinToolingMetadataArtifact: Boolean
         get() = booleanProperty("kotlin.mpp.enableKotlinToolingMetadataArtifact") ?: true
@@ -689,7 +689,7 @@
         val KOTLIN_JS_YARN = property("kotlin.js.yarn")
         val KOTLIN_MPP_PUBLISH_UKLIB = property("kotlin.mpp.publishUklib")
         val KOTLIN_MPP_FAKE_UKLIB_TRANSFORMS = property("kotlin.internal.mpp.fakeUklibTransforms")
-        val KOTLIN_MPP_COMPUTE_UKLIB_CHECKSUM = property("kotlin.internal.mpp.computeUklibChecksum")
+        val KOTLIN_MPP_COMPUTE_TRANSFORMED_LIBRARY_CHECKSUM = property("kotlin.internal.mpp.computeTransformedLibraryChecksum")
         val KOTLIN_MPP_ENABLE_GRANULAR_SOURCE_SETS_METADATA = property("kotlin.mpp.enableGranularSourceSetsMetadata")
         val KOTLIN_MPP_ENABLE_COMPATIBILITY_METADATA_VARIANT = property("kotlin.mpp.enableCompatibilityMetadataVariant")
         val KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION = property("kotlin.mpp.enableCInteropCommonization")
@@ -741,7 +741,7 @@
         val KOTLIN_SWIFT_EXPORT_ENABLED = property("kotlin.experimental.swift-export.enabled")
         val KOTLIN_NATIVE_ENABLE_KLIBS_CROSSCOMPILATION = property("kotlin.native.enableKlibsCrossCompilation")
         val KOTLIN_ARCHIVES_TASK_OUTPUT_AS_FRIEND_ENABLED = property("kotlin.build.archivesTaskOutputAsFriendModule")
-        val KOTLIN_KMP_UKLIB_RESOLUTION_STRATEGY = property("kotlin.kmp.uklibResolutionStrategy")
+        val KOTLIN_KMP_RESOLUTION_STRATEGY = property("kotlin.internal.kmp.kmpResolutionStrategy")
         val KOTLIN_KMP_ISOLATED_PROJECT_SUPPORT = property("kotlin.kmp.isolated-projects.support")
         val KOTLIN_INCREMENTAL_FIR = property("kotlin.incremental.jvm.fir")
 
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt
index 7407f87..9b3c470 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt
@@ -21,7 +21,8 @@
     override val moduleDependencyVersion: String,
     private val kotlinProjectStructureMetadata: KotlinProjectStructureMetadata,
     private val primaryArtifactFile: File,
-    private val hostSpecificArtifactFilesBySourceSetName: Map<String, File>
+    private val hostSpecificArtifactFilesBySourceSetName: Map<String, File>,
+    private val computeChecksum: Boolean = true,
 ) : CompositeMetadataArtifact {
 
     override fun exists(): Boolean {
@@ -107,7 +108,7 @@
                 ?: SourceSetMetadataLayout.METADATA.archiveExtension
 
         override val checksum: String
-            get() = artifactFile.checksum
+            get() = if (computeChecksum) artifactFile.checksum else ""
 
         /**
          * Example:
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt
index 77dc22f..07e5377 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt
@@ -31,6 +31,7 @@
 import org.jetbrains.kotlin.gradle.plugin.mpp.internal.projectStructureMetadataResolvedConfiguration
 import org.jetbrains.kotlin.gradle.plugin.mpp.publishing.KotlinProjectCoordinatesData
 import org.jetbrains.kotlin.gradle.plugin.mpp.publishing.consumeRootModuleCoordinates
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.KmpResolutionStrategy
 import org.jetbrains.kotlin.gradle.plugin.sources.internal
 import org.jetbrains.kotlin.gradle.utils.*
 import java.io.File
@@ -121,7 +122,8 @@
         val sourceSetMetadataLocationsOfProjectDependencies: KotlinProjectSharedDataProvider<SourceSetMetadataLocations>,
         val transformProjectDependencies: Boolean,
         val uklibFragmentAttributes: Set<String>,
-        val computeUklibChecksum: Boolean,
+        val computeTransformedLibraryChecksum: Boolean,
+        val kmpResolutionStrategy: KmpResolutionStrategy,
     ) {
         constructor(project: Project, kotlinSourceSet: KotlinSourceSet, transformProjectDependencies: Boolean = true) : this(
             build = project.currentBuild,
@@ -145,7 +147,8 @@
                 .consumeCommonSourceSetMetadataLocations(kotlinSourceSet.internal.resolvableMetadataConfiguration),
             transformProjectDependencies = transformProjectDependencies,
             uklibFragmentAttributes = kotlinSourceSet.metadataFragmentAttributes.map { it.safeToConsume() }.toSet(),
-            computeUklibChecksum = project.kotlinPropertiesProvider.computeUklibChecksum,
+            computeTransformedLibraryChecksum = project.kotlinPropertiesProvider.computeTransformedLibraryChecksum,
+            kmpResolutionStrategy = project.kotlinPropertiesProvider.kmpResolutionStrategy,
         )
     }
 
@@ -304,11 +307,11 @@
             attributes = uklibFragmentAttributes,
         )
         if (allVisibleFragments.isEmpty()) {
-            throw UklibIsMissingRequiredAttributesException(
-                unzippedUklib = upackedUklibDirectory.file,
-                targetFragmentAttribute = uklibFragmentAttributes.sorted(),
-                availablePlatformFragments = uklibDependency.module.fragments.map { it.identifier }.sorted(),
-            )
+//            throw UklibIsMissingRequiredAttributesException(
+//                unzippedUklib = upackedUklibDirectory.file,
+//                targetFragmentAttribute = uklibFragmentAttributes.sorted(),
+//                availablePlatformFragments = uklibDependency.module.fragments.map { it.identifier }.sorted(),
+//            )
         }
 
         val fragmentsVisibleByThisSourceSet = allVisibleFragments.filterNot {
@@ -334,7 +337,7 @@
                         moduleVersion?.version ?: "unspecified",
                     ),
                     uklibDependency.module.fragments.toList(),
-                    params.computeUklibChecksum,
+                    params.computeTransformedLibraryChecksum,
                 )
             )
         )
@@ -364,7 +367,8 @@
             params.sourceSetName,
             dependency,
             projectStructureMetadata,
-            isResolvedToProject
+            isResolvedToProject,
+            resolveWithLenientPSMResolutionScheme = params.kmpResolutionStrategy == KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently
         )
 
         val allVisibleSourceSets = sourceSetVisibility.visibleSourceSetNames
@@ -383,7 +387,11 @@
 
         val transitiveDependenciesToVisit = module.dependencies
             .filterIsInstance<ResolvedDependencyResult>()
-            .filterTo(mutableSetOf()) { it.toModuleDependencyIdentifier() in requestedTransitiveDependencies }
+            .filterTo(mutableSetOf()) {
+                it.toModuleDependencyIdentifier() in requestedTransitiveDependencies
+                        // Don't filter dependencies in PSM with the lenient resolution model. This is slightly incorrect, but means we see transitive dependencies as in interlibrary dependencies
+                        || params.kmpResolutionStrategy == KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently
+            }
 
         if (params.sourceSetName in params.platformCompilationSourceSets && !isResolvedToProject)
             return MetadataDependencyResolution.Exclude.PublishedPlatformSourceSetDependency(module, transitiveDependenciesToVisit)
@@ -446,7 +454,8 @@
                     moduleDependencyVersion = module.moduleVersion?.version ?: "unspecified",
                     kotlinProjectStructureMetadata = projectStructureMetadata,
                     primaryArtifactFile = compositeMetadataArtifact.file,
-                    hostSpecificArtifactFilesBySourceSetName = hostSpecificMetadataArtifactBySourceSet
+                    hostSpecificArtifactFilesBySourceSetName = hostSpecificMetadataArtifactBySourceSet,
+                    computeChecksum = params.computeTransformedLibraryChecksum
                 )
             )
         }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt
index b90df5b..06a6fea 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt
@@ -33,6 +33,7 @@
 import org.jetbrains.kotlin.gradle.plugin.attributes.KlibPackaging
 import org.jetbrains.kotlin.gradle.plugin.await
 import org.jetbrains.kotlin.gradle.plugin.mpp.publishing.kotlinMultiplatformRootPublication
+import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
 import org.jetbrains.kotlin.gradle.targets.metadata.*
 import org.jetbrains.kotlin.gradle.utils.*
 import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -48,6 +49,8 @@
 
     private val metadataTarget get() = project.multiplatformExtension.metadataTarget
 
+    internal val uklibUsages: CompletableFuture<List<DefaultKotlinUsageContext>> = CompletableFuture()
+
     internal suspend fun subcomponentTargets(): List<KotlinTarget> {
         AfterFinaliseCompilations.await()
         return kotlinTargets
@@ -66,7 +69,20 @@
             }.toSet()
     }
 
-    override fun getVariants(): Set<SoftwareComponent> = _variants.getOrThrow()
+    override fun getVariants(): Set<SoftwareComponent> = if (project.kotlinPropertiesProvider.publishUklib) emptySet() else _variants.getOrThrow()
+
+    private val allUklibUsages: Future<Set<UsageContext>> = project.future {
+        if (project.kotlinPropertiesProvider.publishUklib) {
+            // FIXME: Is there a sane API to get jvm component as a bunch of variants???
+//            val foo = (project.components.named("java") as ComponentWithVariants)
+//            println(foo)
+//            println(project)
+            // FIXME: Drop this KotlinSoftwareComponent garbage and use adhoc component factory when publishing with uklibs. This component maybe should go into a separate -legacy component
+            return@future uklibUsages.await().toSet()
+        } else {
+            return@future emptySet()
+        }
+    }
 
     private val _usages: Future<Set<DefaultKotlinUsageContext>> = project.future {
         metadataTarget.awaitMetadataCompilationsCreated()
@@ -76,6 +92,10 @@
             return@future metadataTarget.createUsageContexts(metadataCompilation)
         }
 
+        if (project.kotlinPropertiesProvider.publishUklib) {
+            return@future emptySet()
+        }
+
         mutableSetOf<DefaultKotlinUsageContext>().apply {
             val allMetadataJar = project.tasks.named(KotlinMetadataTargetConfigurator.ALL_METADATA_JAR_NAME)
             val allMetadataArtifact = project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, allMetadataJar) { allMetadataArtifact ->
@@ -105,7 +125,7 @@
 
 
     override fun getUsages(): Set<UsageContext> {
-        return _usages.getOrThrow().publishableUsages() + includeExtraUsagesFrom.usages
+        return _usages.getOrThrow().publishableUsages() + includeExtraUsagesFrom.usages + allUklibUsages.getOrThrow()
     }
 
     private suspend fun allPublishableCommonSourceSets() = getCommonSourceSetsForMetadataCompilation(project) +
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt
index 3f8665f..18893f8 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt
@@ -23,6 +23,9 @@
     const val KOTLIN_RUNTIME = "kotlin-runtime"
     const val KOTLIN_METADATA = "kotlin-metadata"
 
+    const val KOTLIN_UKLIB_API = "kotlin-uklib-api"
+    const val KOTLIN_UKLIB_RUNTIME = "kotlin-uklib-runtime"
+
     // This type is required to distinguish metadata jar configuration from a psm secondary variant.
     // At the same time, disambiguation and compatibility rules should count them as equivalent
     // to be possible to apply a transform actions chain to `kotlin-metadata` artifact to get psm.
@@ -162,7 +165,7 @@
 
     private class KotlinMetadataDisambiguation : AttributeDisambiguationRule<Usage> {
         override fun execute(details: MultipleCandidatesDetails<Usage>) = details.run {
-            val commonCandidateList = listOf(KOTLIN_METADATA, KOTLIN_API, *javaUsagesForKotlinMetadataConsumers.toTypedArray())
+            val commonCandidateList = listOf(KOTLIN_METADATA, KOTLIN_UKLIB_API, KOTLIN_API, *javaUsagesForKotlinMetadataConsumers.toTypedArray())
             if (consumerValue?.name == KOTLIN_METADATA) {
                 // Prefer Kotlin metadata, but if there's no such variant then accept 'kotlin-api' or the Java usages
                 // (see the compatibility rule):
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt
index 9f46c4f..c9910d4 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt
@@ -109,7 +109,9 @@
         flatMap { resolution ->
             when (resolution) {
                 is MetadataDependencyResolution.ChooseVisibleSourceSets -> resolution.toTransformedLibrariesRecords()
-                is MetadataDependencyResolution.KeepOriginalDependency -> resolution.toTransformedLibrariesRecords()
+                is MetadataDependencyResolution.KeepOriginalDependency -> emptyList()
+                    // wtf why??? Due to compatibility rules in uklibs and dom-api-compat attributes we can get dom-api-compat-in-metadata, but when would we ever want to get this dependency in the classpath???
+//                    resolution.toTransformedLibrariesRecords()
                 is MetadataDependencyResolution.Exclude -> emptyList()
             }
         }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/SourceSetVisibilityProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/SourceSetVisibilityProvider.kt
index f3b53c0..f5c90cf 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/SourceSetVisibilityProvider.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/SourceSetVisibilityProvider.kt
@@ -10,6 +10,7 @@
 import org.gradle.api.artifacts.component.ModuleComponentIdentifier
 import org.gradle.api.artifacts.component.ProjectComponentIdentifier
 import org.gradle.api.artifacts.result.ResolvedDependencyResult
+import org.gradle.api.attributes.Attribute
 import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
 import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
@@ -85,18 +86,31 @@
         resolvedRootMppDependency: ResolvedDependencyResult,
         dependencyProjectStructureMetadata: KotlinProjectStructureMetadata,
         resolvedToOtherProject: Boolean,
+        resolveWithLenientPSMResolutionScheme: Boolean,
     ): SourceSetVisibilityResult {
         val resolvedRootMppDependencyId = resolvedRootMppDependency.selected.id
 
         val platformCompilationsByResolvedVariantName = mutableMapOf<String, PlatformCompilationData>()
 
-        val visiblePlatformVariantNames: List<Set<String>> = platformCompilations
-            .filter { visibleFromSourceSet in it.allSourceSets }
+        val compilationsContainingSourceSetDoingGMT = platformCompilations.filter { visibleFromSourceSet in it.allSourceSets }
+
+        val visiblePlatformVariantNames: List<Set<String>> = compilationsContainingSourceSetDoingGMT
             .mapNotNull { platformCompilationData ->
                 val resolvedPlatformDependencies = platformCompilationData
                     .resolvedDependenciesConfiguration
                     .allResolvedDependencies
                     .filter { it.selected.id isEqualsIgnoringVersion resolvedRootMppDependencyId }
+                    .filterNot {
+                        // Pre lenient resolve logic
+                        if (!resolveWithLenientPSMResolutionScheme) return@filterNot false
+                        // Filter metadata jars resolved from pre Uklib KMP publications
+                        // @see [KotlinPlatformConfigurationsCanResolveMetadata]
+                        it.resolvedVariant.attributes.getAttribute(
+                            KotlinPlatformType.attribute
+                        ) == KotlinPlatformType.common || it.resolvedVariant.attributes.getAttribute(
+                            Attribute.of(KotlinPlatformType.attribute.name, String::class.java)
+                        ) == KotlinPlatformType.common.name
+                    }
                     /*
                     Returning null if we can't find the given dependency in a certain platform compilations dependencies.
                     This is not expected, since this means the dependency does not support the given targets which will
@@ -128,6 +142,11 @@
             return SourceSetVisibilityResult(emptySet(), emptyMap())
         }
 
+        // Means we are looking at a dependency with a subset of targets relative to this source set. Ignore this dependency in this source set
+        if (resolveWithLenientPSMResolutionScheme && compilationsContainingSourceSetDoingGMT.size > visiblePlatformVariantNames.size) {
+            return SourceSetVisibilityResult(emptySet(), emptyMap())
+        }
+
         val visibleSourceSetNames = visiblePlatformVariantNames
             .mapNotNull { platformVariants ->
                 platformVariants
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/publishing/Publishing.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/publishing/Publishing.kt
index 3439137..4e936f3 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/publishing/Publishing.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/publishing/Publishing.kt
@@ -12,10 +12,10 @@
 import org.gradle.api.publish.PublishingExtension
 import org.gradle.api.publish.maven.MavenPublication
 import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
-import org.gradle.jvm.tasks.Jar
+import org.jetbrains.kotlin.gradle.dsl.awaitMetadataTarget
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.Uklib
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication.UklibPomDependenciesRewriter
-import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication.locateOrRegisterArchiveUklibTask
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication.createUklibPublication
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication.locateOrStubJvmJarTask
 import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
 import org.jetbrains.kotlin.gradle.plugin.*
@@ -90,10 +90,9 @@
         UklibPomDependenciesRewriter().rewriteDependencies(it, scopeRewritingMapping.get())
     }
     project.launch {
-        artifact(project.locateOrStubJvmJarTask())
-        artifact(project.locateOrRegisterArchiveUklibTask()) { artifact ->
-            artifact.extension = Uklib.UKLIB_EXTENSION
-        }
+        rootComponent.uklibUsages.complete(
+            project.createUklibPublication()
+        )
     }
 }
 
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/KmpResolutionStrategy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/KmpResolutionStrategy.kt
new file mode 100644
index 0000000..63c06b7
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/KmpResolutionStrategy.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption
+
+internal enum class KmpResolutionStrategy {
+    ResolveUklibsAndResolvePSMLeniently,
+    /**
+     * FIXME: Introduce two modes of Uklib resolution
+     * - Prefer Uklib variants
+     * - Prefer PSM variants
+     */
+    StandardKMPResolution;
+
+    val propertyName: String
+        get() = when (this) {
+            ResolveUklibsAndResolvePSMLeniently -> "resolveUklibsAndResolvePSMLeniently"
+            StandardKMPResolution -> "standardKMPResolution"
+        }
+
+    companion object {
+        fun fromProperty(name: String): KmpResolutionStrategy? = when (name) {
+            ResolveUklibsAndResolvePSMLeniently.propertyName -> ResolveUklibsAndResolvePSMLeniently
+            StandardKMPResolution.propertyName -> StandardKMPResolution
+            else -> null
+        }
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/ThrowAwayMetadataJarsTransform.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/ThrowAwayMetadataJarsTransform.kt
new file mode 100644
index 0000000..b06bc13
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/ThrowAwayMetadataJarsTransform.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption
+
+import org.gradle.api.artifacts.transform.InputArtifact
+import org.gradle.api.artifacts.transform.TransformAction
+import org.gradle.api.artifacts.transform.TransformOutputs
+import org.gradle.api.artifacts.transform.TransformParameters
+import org.gradle.api.file.FileSystemLocation
+import org.gradle.api.provider.Property
+import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.PathSensitive
+import org.gradle.api.tasks.PathSensitivity
+import org.gradle.work.DisableCachingByDefault
+import java.util.zip.ZipFile
+
+@DisableCachingByDefault(because = "Investigate caching uklib transforms")
+internal abstract class ThrowAwayMetadataJarsTransform : TransformAction<ThrowAwayMetadataJarsTransform.Parameters> {
+    interface Parameters : TransformParameters {
+        @get:Input
+        // FIXME: Fake metadata jar?
+        val fakeUklibUnzip: Property<Boolean>
+    }
+
+    @get:PathSensitive(PathSensitivity.RELATIVE)
+    @get:InputArtifact
+    abstract val inputArtifact: Provider<FileSystemLocation>
+
+    override fun transform(outputs: TransformOutputs) {
+        val jar = inputArtifact.get().asFile
+        // Sanity check
+        if (jar.extension != "jar") {
+            // Just return whatever this is
+            outputs.file(jar)
+            return
+        }
+
+        val isMetadataJar: Boolean = if (parameters.fakeUklibUnzip.get())
+            false
+        else ZipFile(jar).use { zip ->
+            zip.entries().asSequence().any {
+                it.name.endsWith("kotlin-project-structure-metadata.json")
+            }
+        }
+        // Return nothing on metadata jar
+        if (isMetadataJar) return
+        outputs.file(jar)
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt
index d264d89..1ac5905 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt
@@ -8,12 +8,18 @@
 import org.gradle.api.NamedDomainObjectCollection
 import org.gradle.api.NamedDomainObjectContainer
 import org.gradle.api.Project
+import org.gradle.api.attributes.*
+import org.gradle.api.attributes.Usage.*
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.uklibFragmentPlatformAttribute
 import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
 import org.jetbrains.kotlin.gradle.plugin.*
-import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseCompilations
 import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
 import org.jetbrains.kotlin.gradle.plugin.mpp.*
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.KOTLIN_API
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.KOTLIN_METADATA
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.KOTLIN_RUNTIME
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.KOTLIN_UKLIB_API
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.KOTLIN_UKLIB_RUNTIME
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.Uklib
 import org.jetbrains.kotlin.gradle.plugin.sources.internal
 import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
@@ -21,9 +27,9 @@
 import org.jetbrains.kotlin.gradle.utils.setAttribute
 
 internal val UklibConsumptionSetupAction = KotlinProjectSetupAction {
-    when (project.kotlinPropertiesProvider.uklibResolutionStrategy) {
-        UklibResolutionStrategy.ResolveUklibsInMavenComponents -> setupUklibConsumption()
-        UklibResolutionStrategy.IgnoreUklibs -> { /* do nothing */ }
+    when (project.kotlinPropertiesProvider.kmpResolutionStrategy) {
+        KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently -> setupUklibConsumption()
+        KmpResolutionStrategy.StandardKMPResolution -> { /* do nothing */ }
     }
 }
 
@@ -37,10 +43,15 @@
     val sourceSets = multiplatformExtension.sourceSets
     val targets = multiplatformExtension.targets
 
+    dependencies.attributesSchema.attribute(USAGE_ATTRIBUTE) { strategy ->
+        strategy.compatibilityRules.add(KotlinApiMetadataAndRuntimeCanConsumeKotlinUklibApi::class.java)
+    }
+
     registerCompressedUklibArtifact()
     allowUklibsToDecompress()
     allowMetadataConfigurationsToResolveUnzippedUklib(sourceSets)
     allowPlatformCompilationsToResolvePlatformCompilationArtifactFromUklib(targets)
+    allowPSMBasedKMPToResolveLeniently(targets)
 }
 
 private fun Project.allowPlatformCompilationsToResolvePlatformCompilationArtifactFromUklib(
@@ -76,6 +87,16 @@
 
         // FIXME: Refactor this and encode what configurations should be allowed to transform per KotlinTarget somewhere around [uklibFragmentPlatformAttribute]
         target.compilations.configureEach {
+            // We have to invert all resolvable configurations, so that they don't prefer jvm compatibility variant in uklib publication
+            with(it.internal.configurations.compileDependencyConfiguration.attributes) {
+                setAttribute(USAGE_ATTRIBUTE, usageByName(KOTLIN_UKLIB_API))
+            }
+            it.internal.configurations.runtimeDependencyConfiguration?.attributes?.let {
+                with(it) {
+                    setAttribute(USAGE_ATTRIBUTE, usageByName(KOTLIN_UKLIB_RUNTIME))
+                }
+            }
+
             listOfNotNull(
                 it.internal.configurations.compileDependencyConfiguration,
                 it.internal.configurations.runtimeDependencyConfiguration,
@@ -115,4 +136,126 @@
     }
 }
 
+private class KotlinApiMetadataAndRuntimeCanConsumeKotlinUklibApi : AttributeCompatibilityRule<Usage> {
+    override fun execute(details: CompatibilityCheckDetails<Usage>) = with(details) {
+        val consumerUsage = consumerValue?.name ?: return@with
+        val producerUsage = producerValue?.name ?: return@with
+        // Allow consuming Uklibs in all existing configurations
+        if (
+            mapOf(
+                KOTLIN_METADATA to setOf(KOTLIN_UKLIB_API),
+//                KOTLIN_API to setOf(KOTLIN_UKLIB_API),
+//                KOTLIN_RUNTIME to setOf(KOTLIN_UKLIB_API, KOTLIN_UKLIB_RUNTIME),
+            )[consumerUsage]?.contains(producerUsage) == true
+        ) compatible()
+    }
+}
 
+/**
+ * Use a nuclear compatibility rules to allow lenient interlibrary resolution of KMP dependencies. When platform configuration is going to
+ * resolve for GMT or for platform compilation, it will be allowed to fallback to metadata variant. S
+ *
+ * - Klib compilations already filter out jar files
+ * - For GMT there is further special handling
+ * - FIXME: jvm and android will receive 1 garbage jar? Can we write a transform to check for metadata jar? Check for presence of META-INF/kotlin-project-structure-metadata.json?
+ */
+private fun Project.allowPSMBasedKMPToResolveLeniently(
+    targets: NamedDomainObjectCollection<KotlinTarget>
+) {
+    dependencies.attributesSchema.attribute(USAGE_ATTRIBUTE) { strategy ->
+        strategy.compatibilityRules.add(AllowPlatformConfigurationsToFallBackToMetadataForLenientKmpResolutionUsage::class.java)
+        strategy.disambiguationRules.add(DisambiguatePlatformConfigurationsToFallBackToMetadataForLenientKmpResolutionUsage::class.java)
+    }
+    dependencies.attributesSchema.attribute(KotlinPlatformType.attribute) { strategy ->
+        strategy.compatibilityRules.add(AllowPlatformConfigurationsToFallBackToMetadataForLenientKmpResolution::class.java)
+    }
+    with(dependencies.artifactTypes.getByName("jar").attributes) {
+        setAttribute(isMetadataJar, isMetadataJarUnknown)
+    }
+    dependencies.registerTransform(ThrowAwayMetadataJarsTransform::class.java) {
+        it.from.setAttribute(isMetadataJar, isMetadataJarUnknown)
+        it.to.setAttribute(isMetadataJar, notMetadataJar)
+        it.parameters.fakeUklibUnzip.set(kotlinPropertiesProvider.fakeUkibTransforms)
+    }
+    targets.configureEach {
+        if (it is KotlinNativeTarget || it is KotlinJsIrTarget || it is KotlinJvmTarget
+            // || it is KotlinAndroidTarget
+            ) {
+            it.compilations.configureEach {
+                listOfNotNull(
+                    it.internal.configurations.compileDependencyConfiguration,
+                    it.internal.configurations.runtimeDependencyConfiguration,
+                ).forEach {
+                    with(it.attributes) {
+                        setAttribute(isMetadataJar, notMetadataJar)
+                    }
+                }
+            }
+        }
+    }
+}
+
+private class AllowPlatformConfigurationsToFallBackToMetadataForLenientKmpResolution : AttributeCompatibilityRule<KotlinPlatformType> {
+    override fun execute(details: CompatibilityCheckDetails<KotlinPlatformType>) = with(details) {
+        consumerValue?.name ?: return@with
+        val producer = producerValue?.name ?: return@with
+        if (producer == KotlinPlatformType.common.name) compatible()
+    }
+}
+
+private class AllowPlatformConfigurationsToFallBackToMetadataForLenientKmpResolutionUsage : AttributeCompatibilityRule<Usage> {
+    override fun execute(details: CompatibilityCheckDetails<Usage>) = with(details) {
+        val consumerUsage = consumerValue?.name ?: return@with
+        val producerUsage = producerValue?.name ?: return@with
+        if (
+            mapOf(
+                // Platform compile dependency configuration
+                KOTLIN_UKLIB_API to setOf(
+                    // Allow uklib consumer to resolve regular KMP platform apiElements. The exact selection is still controlled with other attributes
+                    KOTLIN_API,
+                    // FIXME: Allow selecting java-only? Test this
+                    JAVA_API,
+                    // Fallback to metadata variant to inherit dependencies like in uklib publication
+                    // stdlib doesn't have native variants, so for native platform configuration must fall back here
+                    // runtime also???
+                    KOTLIN_METADATA
+                ),
+                // FIXME: Test these
+                KOTLIN_UKLIB_RUNTIME to setOf(KOTLIN_API, KOTLIN_RUNTIME, JAVA_RUNTIME),
+
+                // but dom-api-compat has compatibility variant, but the usage is wrong, what???
+                KOTLIN_METADATA to setOf(KOTLIN_API),
+            )[consumerUsage]?.contains(producerUsage) == true
+        ) compatible()
+    }
+}
+
+private class DisambiguatePlatformConfigurationsToFallBackToMetadataForLenientKmpResolutionUsage : AttributeDisambiguationRule<Usage> {
+    override fun execute(details: MultipleCandidatesDetails<Usage>) = details.run {
+        val consumerUsage = consumerValue?.name ?: return@run
+
+        mapOf(
+            KOTLIN_UKLIB_API to listOf(
+                // We are selecting for platform compilation. Prefer platform apiElements if it is available
+                KOTLIN_API,
+                // FIXME: Check if this is correct
+                JAVA_API,
+                // Fallback to metadata if platform apiElements is not available. In GMT this selection is filtered to determine visibility
+                KOTLIN_METADATA
+            ),
+            KOTLIN_UKLIB_RUNTIME to listOf(KOTLIN_RUNTIME, KOTLIN_API, JAVA_RUNTIME, JAVA_API, KOTLIN_METADATA),
+        )[consumerUsage]?.let {
+            closestMatchToFirstAppropriateCandidate(it)
+        }
+        return@run
+    }
+
+    private fun MultipleCandidatesDetails<Usage>.closestMatchToFirstAppropriateCandidate(acceptedProducerValues: List<String>) {
+        val candidatesMap = candidateValues.associateBy { it.name }
+        acceptedProducerValues.firstOrNull { it in candidatesMap }?.let { closestMatch(candidatesMap.getValue(it)) }
+    }
+}
+
+private val isMetadataJar = Attribute.of("org.jetbrains.kotlin.isMetadataJar", String::class.java)
+internal val isMetadataJarUnknown = "unknown"
+internal val notMetadataJar = "non-a-metadata-jar"
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibResolutionStrategy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibResolutionStrategy.kt
deleted file mode 100644
index 5a98508..0000000
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibResolutionStrategy.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
- * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
- */
-
-package org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption
-
-internal enum class UklibResolutionStrategy {
-    ResolveUklibsInMavenComponents,
-    IgnoreUklibs;
-
-    val propertyName: String
-        get() = when (this) {
-            ResolveUklibsInMavenComponents -> "resolveUklibsInMavenComponents"
-            IgnoreUklibs -> "ignoreUklibs"
-        }
-
-    companion object {
-        fun fromProperty(name: String): UklibResolutionStrategy? = when (name) {
-            ResolveUklibsInMavenComponents.propertyName -> ResolveUklibsInMavenComponents
-            IgnoreUklibs.propertyName -> IgnoreUklibs
-            else -> null
-        }
-    }
-}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UnzippedUklibToPlatformCompilationTransform.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UnzippedUklibToPlatformCompilationTransform.kt
index 4106dbd..5ab84c0 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UnzippedUklibToPlatformCompilationTransform.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UnzippedUklibToPlatformCompilationTransform.kt
@@ -58,17 +58,20 @@
              *
              * Should we check this case and silently ignore this case here by detecting that the file is not present?
              */
-            throw PlatformCompilationTransformException(
-                unzippedUklib,
-                targetFragmentAttribute,
-                uklib.module.fragments.map { it.identifier }.sorted()
-            )
+            // FIXME: 02.02.2025 - Now we no longer need this
+//            throw PlatformCompilationTransformException(
+//                unzippedUklib,
+//                targetFragmentAttribute,
+//                uklib.module.fragments.map { it.identifier }.sorted()
+//            )
         }
 
         if (platformFragments.size > 1) {
             error("Matched multiple fragments from ${unzippedUklib}, but was expecting to find exactly one. Found fragments: $platformFragments")
         }
 
-        outputs.dir(platformFragments.single().file())
+        platformFragments.singleOrNull()?.let {
+            outputs.dir(it.file())
+        }
     }
 }
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/uklibTransformationAttributes.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/uklibTransformationAttributes.kt
index 3414c72..4f7eaff 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/uklibTransformationAttributes.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/uklibTransformationAttributes.kt
@@ -8,6 +8,7 @@
 import org.gradle.api.artifacts.result.ResolvedArtifactResult
 import org.gradle.api.attributes.Attribute
 import org.gradle.api.attributes.AttributeContainer
+import org.gradle.api.attributes.Usage
 
 // Means this is uklib itself of a platform fragment transformed from the uklib
 internal val ResolvedArtifactResult.isFromUklib: Boolean
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/diagnostics/UklibFromKGPSourceSetsDependenciesChecker.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/diagnostics/UklibFromKGPSourceSetsDependenciesChecker.kt
index 49cd454..adc2135 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/diagnostics/UklibFromKGPSourceSetsDependenciesChecker.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/diagnostics/UklibFromKGPSourceSetsDependenciesChecker.kt
@@ -40,6 +40,9 @@
 
         fun Configuration.declaredDependencies() = incoming.dependencies.filterNot {
             it.group == KOTLIN_MODULE_GROUP && it.name in ignoreDependenciesInsertedByDefault
+        }.filterNot {
+            false
+//            it is NpmDependency ???
         }.toSet()
 
         val compilationDependencies = uklibPublishedPlatformCompilations.associate {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/ArchiveUklibTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/ArchiveUklibTask.kt
index 7672849..b5a453f 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/ArchiveUklibTask.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/ArchiveUklibTask.kt
@@ -28,11 +28,13 @@
 
     @get:OutputFile
     val outputZip: RegularFileProperty = project.objects.fileProperty().convention(
+        // fixme: use convention name + output locations
         project.layout.buildDirectory.file("library.${Uklib.UKLIB_EXTENSION}")
     )
 
     @get:Internal
     val temporariesDirectory: DirectoryProperty = project.objects.directoryProperty().convention(
+        // fixme: use streams instead tmp files
         project.layout.buildDirectory.dir("uklibTemp")
     )
 
@@ -56,6 +58,11 @@
          */
         val compiledFragments = this.fragmentsWithTransitiveRefinees.get().filterKeys { fragment ->
             val isMetadata = fragment.attributes.count() > 1
+            // write code in nativeMain
+            // compile
+            // realize that all nativeMain can be moved to commonMain. Move it
+            // compile again
+            // all good and nice, publish it!
             if (isMetadata && !fragment.file().exists()) {
                 return@filterKeys false
             }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibFromKGPModel.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibFromKGPModel.kt
index a793c32..6e88ea4 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibFromKGPModel.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibFromKGPModel.kt
@@ -6,6 +6,7 @@
 package org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication
 
 import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
 import org.gradle.api.provider.Provider
 import org.gradle.api.tasks.TaskProvider
 import org.gradle.jvm.tasks.Jar
@@ -36,6 +37,7 @@
     val refineesTransitiveClosure: Set<String>,
     val providingTask: TaskProvider<*>,
     val outputFile: Provider<File>,
+    val compilation: KotlinCompilation<*>,
 )
 
 internal suspend fun KotlinMultiplatformExtension.validateKgpModelIsUklibCompliantAndCreateKgpFragments(): List<KGPUklibFragment> {
@@ -70,6 +72,7 @@
                 fragments.add(kgpUklibFragment(mainCompilation, jarTask, jarArtifact))
             }
             else -> {
+
                 when (val attribute = target.uklibFragmentPlatformAttribute) {
                     is UklibFragmentPlatformAttribute.PublishAndConsumeInMetadataCompilations -> { /* Do nothing for AGP */ }
                     is UklibFragmentPlatformAttribute.PublishAndConsumeInAllCompilations -> { error("Unexpected") }
@@ -87,11 +90,22 @@
         return emptyList()
     }
 
+    // On Linux Host (iosMain is not publishable)
+    //
+    // Metadata Compilation:
+    // P = Publishable compilations/default source sets on Platform Targets -> (jvmMain, iosX64Main, ...) NO TEST!
+    // for each intermediate source set all targets should be part of P
+    // commonTest -> jvmTest, iosX64Test, ...
+    //
+    // Metadata compilations are ALL ABOUT PUBLICATION!!!! to teach consumer's IDEs to see intermediate source sets!
+    //
+
     val publishedMetadataCompilations = awaitMetadataTarget().publishedMetadataCompilations()
     publishedMetadataCompilations.forEach { metadataCompilation ->
         val artifact = metadataCompilation.project.provider {
             metadataCompilation.metadataPublishedArtifacts.singleFile
         }
+        // FIXME: Remove this
         unsupportedTargets.addAll(
             metadataCompilation.metadataFragmentAttributes.filterIsInstance<UklibFragmentPlatformAttribute.FailOnPublicationAndUseTargetNameForMetadataCompilations>().map {
                 it.unsupportedTargetName
@@ -112,6 +126,7 @@
                 refineesTransitiveClosure = metadataCompilation.refineesTransitiveClosure(),
                 providingTask = metadataCompilation.compileTaskProvider,
                 outputFile = artifact,
+                compilation = metadataCompilation,
             )
         )
     }
@@ -176,6 +191,7 @@
     refineesTransitiveClosure = mainCompilation.refineesTransitiveClosure(),
     providingTask = artifactProvidingTask,
     outputFile = file,
+    compilation = mainCompilation,
 )
 
 private fun KotlinCompilation<*>.refineesTransitiveClosure(): Set<String> = internal.allKotlinSourceSets
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibPomDependenciesRewriter.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibPomDependenciesRewriter.kt
index 926a448..f7629ec 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibPomDependenciesRewriter.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/UklibPomDependenciesRewriter.kt
@@ -40,6 +40,7 @@
 
             // Leave if it's already compile
             if (scope?.text() == "compile") return@forEach
+            // FIXME: Drop this and rewrite everything to compile
             scopeMapping[DependencyGA(group, artifact)]?.let {
                 when (it) {
                     KotlinUsageContext.MavenScope.COMPILE -> scope?.setValue("compile")
@@ -81,7 +82,7 @@
                             }
                     }.forEach { set ->
                         set.dependencySet.forEach { dependency ->
-                            val dep = DependencyGA(dependency.group, dependency.name)
+                            val dep = DependencyGA(dependency.group, dependency.name) // mavenPublication {customArtifact = "custom" group = "custom" }
                             val exScope = dependencyRemapping[dep]
                             when (exScope) {
                                 KotlinUsageContext.MavenScope.COMPILE -> {}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/locateOrRegisterArchiveUklibTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/locateOrRegisterArchiveUklibTask.kt
index d506e3d..0446ce7 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/locateOrRegisterArchiveUklibTask.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/publication/locateOrRegisterArchiveUklibTask.kt
@@ -6,16 +6,27 @@
 package org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication
 
 import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.attributes.Category
+import org.gradle.api.attributes.Usage
 import org.gradle.api.tasks.TaskProvider
 import org.gradle.jvm.tasks.Jar
+import org.jetbrains.kotlin.gradle.dsl.awaitMetadataTarget
 import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
+import org.jetbrains.kotlin.gradle.plugin.*
+import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
+import org.jetbrains.kotlin.gradle.plugin.categoryByName
+import org.jetbrains.kotlin.gradle.plugin.mpp.*
+import org.jetbrains.kotlin.gradle.plugin.mpp.internal
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.Uklib
+import org.jetbrains.kotlin.gradle.plugin.usageByName
 import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
 import org.jetbrains.kotlin.gradle.tasks.locateTask
+import org.jetbrains.kotlin.gradle.utils.createConsumable
 
-internal suspend fun Project.locateOrRegisterArchiveUklibTask(): TaskProvider<ArchiveUklibTask> {
+
+internal suspend fun Project.createUklibPublication(): List<DefaultKotlinUsageContext> {
     val taskName = "archiveUklib"
-    tasks.locateTask<ArchiveUklibTask>(taskName)?.let { return it }
-
     val archiveUklib = tasks.register(taskName, ArchiveUklibTask::class.java)
 
     val kgpFragments = multiplatformExtension.validateKgpModelIsUklibCompliantAndCreateKgpFragments()
@@ -37,7 +48,123 @@
         )
     }
 
-    return archiveUklib
+    return setupOutgoingUklibConfigurations(
+        archiveUklib,
+        kgpFragments
+    )
+}
+
+internal suspend fun Project.setupOutgoingUklibConfigurations(
+    archiveTask: TaskProvider<ArchiveUklibTask>,
+    publishedCompilations: List<KGPUklibFragment>,
+): List<DefaultKotlinUsageContext> {
+    val uklibApiElements = "uklibApiElements"
+    val uklibRuntimeElements = "uklibRuntimeElements"
+
+    configurations.createConsumable(uklibApiElements) {
+        attributes.apply {
+            attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_UKLIB_API))
+            attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+        }
+        publishedCompilations.forEach {
+            extendsFrom(
+                it.compilation.internal.configurations.apiConfiguration
+            )
+            if (it.compilation is KotlinNativeCompilation) {
+                extendsFrom(it.compilation.internal.configurations.implementationConfiguration)
+            }
+        }
+    }
+    configurations.createConsumable(uklibRuntimeElements) {
+        attributes.apply {
+            attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_UKLIB_RUNTIME))
+            attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+        }
+        publishedCompilations.forEach {
+            it.compilation.internal.configurations.runtimeDependencyConfiguration?.let {
+                extendsFrom(it)
+            }
+        }
+    }
+
+    project.artifacts.add(uklibApiElements, archiveTask) {
+        it.extension = Uklib.UKLIB_EXTENSION
+    }
+    project.artifacts.add(uklibRuntimeElements, archiveTask) {
+        it.extension = Uklib.UKLIB_EXTENSION
+    }
+
+    KotlinPluginLifecycle.Stage.AfterFinaliseCompilations.await()
+    val metadataTarget = multiplatformExtension.awaitMetadataTarget()
+    val variants = mutableListOf(
+        DefaultKotlinUsageContext(
+            // Whatever, this compilation doesn't matter
+            compilation = metadataTarget.compilations.getByName("main"),
+            dependencyConfigurationName = uklibRuntimeElements,
+            includeIntoProjectStructureMetadata = false,
+        ),
+        DefaultKotlinUsageContext(
+            // Whatever, this compilation doesn't matter
+            compilation = metadataTarget.compilations.getByName("main"),
+            dependencyConfigurationName = uklibApiElements,
+            includeIntoProjectStructureMetadata = false,
+        )
+    )
+
+    val jar = locateOrStubJvmJarTask()
+    val jvmApiElements = "uklib-jvmApiElements"
+    val jvmRuntimeElements = "uklib-jvmRuntimeElements"
+    configurations.createConsumable(jvmApiElements) {
+        attributes.apply {
+            attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API))
+            attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+        }
+        publishedCompilations.forEach {
+            extendsFrom(
+                it.compilation.internal.configurations.apiConfiguration
+            )
+            if (it.compilation is KotlinNativeCompilation) {
+                extendsFrom(it.compilation.internal.configurations.implementationConfiguration)
+            }
+        }
+    }
+    configurations.createConsumable(jvmRuntimeElements) {
+        attributes.apply {
+            attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_RUNTIME))
+            attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
+        }
+        publishedCompilations.forEach {
+            it.compilation.internal.configurations.runtimeDependencyConfiguration?.let {
+                extendsFrom(it)
+            }
+        }
+    }
+    project.artifacts.add(jvmApiElements, jar) {
+        it.extension = "jar"
+    }
+    project.artifacts.add(jvmRuntimeElements, jar) {
+        it.extension = "jar"
+    }
+
+    val jvmComp: KotlinCompilation<*> = publishedCompilations.singleOrNull {
+        it.compilation is KotlinJvmCompilation
+    }?.compilation ?: metadataTarget.compilations.getByName("main")
+    variants.addAll(
+        listOf(
+            DefaultKotlinUsageContext(
+                compilation = jvmComp,
+                dependencyConfigurationName = jvmApiElements,
+                includeIntoProjectStructureMetadata = false,
+            ),
+            DefaultKotlinUsageContext(
+                compilation = jvmComp,
+                dependencyConfigurationName = jvmRuntimeElements,
+                includeIntoProjectStructureMetadata = false,
+            ),
+        )
+    )
+
+    return variants
 }
 
 internal suspend fun Project.locateOrStubJvmJarTask(): TaskProvider<Jar> {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt
index b1b2674..c527cf4 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/BuildFusService.kt
@@ -85,8 +85,8 @@
             registerIfAbsentImpl(project, pluginVersion, buildUidService).also { serviceProvider ->
                 SingleActionPerProject.run(project, UsesBuildFusService::class.java.name) {
                     project.tasks.withType<UsesBuildFusService>().configureEach { task ->
-                        task.buildFusService.value(serviceProvider).disallowChanges()
-                        task.usesService(serviceProvider)
+//                        task.buildFusService.value(serviceProvider).disallowChanges()
+//                        task.usesService(serviceProvider)
                     }
                 }
             }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FlowActionBuildFusService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FlowActionBuildFusService.kt
index 58b1187..1715201 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FlowActionBuildFusService.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/FlowActionBuildFusService.kt
@@ -59,7 +59,7 @@
     fun getConfigurationTimeMetrics(): Provider<List<MetricContainer>> {
         return providerFactory.provider {
             synchronized(this) {
-                configurationMetrics.disallowChanges()
+//                configurationMetrics.disallowChanges()
                 configurationMetrics.get()
             }
         }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt
index 6b47b15..85809ff 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt
@@ -157,6 +157,7 @@
              * source set.
              * See also: [buildKotlinProjectStructureMetadata], where these dependencies must be included into the source set exported deps.
              */
+            // FIXME: Maybe tie this to the uklib apiElements configuration
             if (isSharedNativeCompilation) {
                 sourceSet.internal.withDependsOnClosure.forEach { hierarchySourceSet ->
                     apiElementsConfiguration.extendsFrom(
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/PP.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/PP.kt
new file mode 100644
index 0000000..d17d943
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/PP.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.unitTests.uklibs
+
+import kotlin.reflect.full.memberProperties
+import kotlin.test.assertEquals
+
+class PP(
+    val value: Any,
+    val indentation: Int,
+) {
+    override fun toString(): String {
+        val twoSpaces = " ".repeat(2)
+        val indentationSpace = " ".repeat(indentation)
+        val nextIndentationDepth = indentation + 2
+        val elements: Array<String> = when (value) {
+            is Map<*, *> -> arrayOf(
+                "mutableMapOf(",
+                *value.map { it }.sortedBy { it.key.toString() }.map {
+                    "${twoSpaces}${it.key?.pp()} to ${it.value?.pp(nextIndentationDepth)},"
+                }.toTypedArray(),
+                ")",
+            )
+            is Iterable<*> -> {
+                val innerValue = value.map { "${twoSpaces}${it?.pp(nextIndentationDepth)}," }.toTypedArray()
+                when (value) {
+                    is Set<*> -> arrayOf(
+                        "mutableSetOf(",
+                        *innerValue,
+                        ")",
+                    )
+                    is List<*> -> arrayOf(
+                        "mutableListOf(",
+                        *innerValue,
+                        ")",
+                    )
+                    else -> arrayOf(
+                        "mutableListOf(",
+                        *innerValue,
+                        ")",
+                    )
+                }
+            }
+            else -> {
+                val packageName = value::class.java.packageName
+                if (packageName.startsWith("kotlin.") || packageName.startsWith("java.")) {
+                    if (value is String) {
+                        arrayOf("\"${value}\"")
+                    } else {
+                        arrayOf(value.toString())
+                    }
+                } else {
+                    val kClass = value::class
+                    arrayOf(
+                        "${kClass.simpleName}(",
+                        *kClass.memberProperties.map { prop ->
+                            "${twoSpaces}${prop.name} = ${prop.getter.call(value)?.pp(nextIndentationDepth)},"
+                        }.toTypedArray(),
+                        ")",
+                    )
+                }
+            }
+        }
+
+        if (elements.size == 1) return elements[0]
+
+        return (listOf(elements[0]) + elements.toList().subList(1, elements.size).map { "${indentationSpace}${it}" }).joinToString("\n")
+    }
+
+    override fun hashCode(): Int {
+        return value.hashCode()
+    }
+
+    override fun equals(other: Any?): Boolean {
+        var otherUnwrapped = other
+        if (other is PP) otherUnwrapped = other.value
+        return value.equals(otherUnwrapped)
+    }
+}
+
+fun Any.pp(indentation: Int = 0): PP = PP(this, indentation)
+
+fun <T> assertEqualsPP(expected: T, actual: T) {
+//    if (expected != actual) {
+//        println(actual?.pp())
+//    }
+    assertEquals((expected as Any).pp(), (actual as Any).pp())
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/PPTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/PPTest.kt
new file mode 100644
index 0000000..e04fb09
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/PPTest.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.unitTests.uklibs
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class PPTest {
+
+    @Test
+    fun test() {
+        val immutable: Any = listOf("a")
+        val mutable: Any = mutableListOf("m")
+
+        fun foo(value: Any) {
+            when (value) {
+                is MutableList<*> -> {
+                }
+                is List<*> -> {
+                    println("List: ${value}, ${value.javaClass}, ${List::class.java.isInstance(value)}")
+                }
+            }
+        }
+
+        foo(mutable)
+        foo(immutable)
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTesting.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTesting.kt
new file mode 100644
index 0000000..d54ac43
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTesting.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.unitTests.uklibs
+
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.attributes.Attribute
+import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
+import org.jetbrains.kotlin.gradle.plugin.mpp.internal
+import org.jetbrains.kotlin.gradle.utils.projectPathOrNull
+
+data class ResolvedComponentWithArtifacts(
+    val configuration: String,
+    val artifacts: MutableList<Map<String, String>> = mutableListOf(),
+) : java.io.Serializable
+
+fun Configuration.resolveProjectDependencyComponentsWithArtifacts(): Map<String, ResolvedComponentWithArtifacts> {
+    val artifacts = resolveProjectDependencyVariantsFromArtifacts().filterNot { it.path == ":" }
+    val components = resolveProjectDependencyComponents().filterNot { it.path == ":" }
+    val componentToArtifacts = LinkedHashMap<String, ResolvedComponentWithArtifacts>()
+    components.forEach { component ->
+        if (componentToArtifacts[component.path] == null) {
+            componentToArtifacts[component.path] = ResolvedComponentWithArtifacts(component.configuration)
+        } else {
+            error("${component} resolved multiple times?")
+        }
+    }
+    artifacts.forEach { artifact ->
+        componentToArtifacts[artifact.path]?.let {
+            it.artifacts.add(artifact.attributes)
+        } ?: error("Missing resolved component for artifact: ${artifact}")
+    }
+    return componentToArtifacts
+}
+
+fun KotlinTarget.compilationResolution(compilationName: String = "main") = compilations
+    .getByName(compilationName).internal.configurations.compileDependencyConfiguration
+    .resolveProjectDependencyComponentsWithArtifacts()
+
+private data class ResolvedVariant(
+    val path: String,
+    val attributes: Map<String, String>,
+)
+
+private data class ResolvedComponent(
+    val path: String,
+    val configuration: String,
+)
+
+private fun Configuration.resolveProjectDependencyVariantsFromArtifacts(): List<ResolvedVariant> {
+    return incoming.artifacts.artifacts
+        .map { artifact ->
+            val uklibAttributes: List<Attribute<*>> = artifact.variant.attributes.keySet()
+                .sortedBy { it.name }
+            ResolvedVariant(
+                artifact.variant.owner.projectPathOrNull ?: artifact.variant.owner.displayName,
+                uklibAttributes.associateBy({ it }) {
+                    artifact.variant.attributes.getAttribute(it).toString()
+                }.mapKeys { it.key.name }
+            )
+        }
+}
+
+private fun Configuration.resolveProjectDependencyComponents(): List<ResolvedComponent> {
+    return incoming.resolutionResult.allComponents
+        .map { component ->
+            ResolvedComponent(
+                component.id.projectPathOrNull ?: component.id.displayName,
+                // Expect a single variant to always be selected?
+                component.variants.single().displayName
+            )
+        }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt
new file mode 100644
index 0000000..7a322c5
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.unitTests.uklibs
+
+val uklibTransformationIosArm64Attributes = mapOf(
+    "artifactType" to "uklib",
+    "org.jetbrains.kotlin.uklibView" to "ios_arm64",
+    "org.jetbrains.kotlin.uklibState" to "decompressed",
+)
+val uklibTransformationJvmAttributes = mapOf(
+    "artifactType" to "uklib",
+    "org.jetbrains.kotlin.uklibView" to "jvm",
+    "org.jetbrains.kotlin.uklibState" to "decompressed",
+)
+val uklibTransformationMetadataAttributes = mapOf(
+    "artifactType" to "uklib",
+    "org.jetbrains.kotlin.uklibView" to "whole_uklib",
+    "org.jetbrains.kotlin.uklibState" to "decompressed",
+)
+val uklibTransformationJsAttributes = mapOf(
+    "artifactType" to "uklib",
+    "org.jetbrains.kotlin.uklibView" to "js_ir",
+    "org.jetbrains.kotlin.uklibState" to "decompressed",
+)
+val uklibTransformationWasmJsAttributes = mapOf(
+    "artifactType" to "uklib",
+    "org.jetbrains.kotlin.uklibView" to "wasm_js",
+    "org.jetbrains.kotlin.uklibState" to "decompressed",
+)
+val uklibTransformationWasmWasiAttributes = mapOf(
+    "artifactType" to "uklib",
+    "org.jetbrains.kotlin.uklibView" to "wasm_wasi",
+    "org.jetbrains.kotlin.uklibState" to "decompressed",
+)
+val uklibVariantAttributes = mapOf(
+    "org.gradle.category" to "library",
+    "org.gradle.usage" to "kotlin-uklib-api",
+)
+val jvmRuntimeAttributes = mapOf(
+    "org.gradle.category" to "library",
+    "org.gradle.libraryelements" to "jar",
+    "org.gradle.status" to "release",
+    "org.gradle.usage" to "java-runtime",
+)
+val jvmApiAttributes = mapOf(
+    "org.gradle.category" to "library",
+    "org.gradle.libraryelements" to "jar",
+    "org.gradle.status" to "release",
+    "org.gradle.usage" to "java-api",
+)
+val kmpJvmRuntimeVariantAttributes = mapOf(
+    "org.gradle.category" to "library",
+    "org.gradle.jvm.environment" to "standard-jvm",
+    "org.gradle.libraryelements" to "jar",
+    "org.gradle.usage" to "java-runtime",
+    "org.jetbrains.kotlin.platform.type" to "jvm",
+)
+val kmpJvmApiVariantAttributes = mapOf(
+    "org.gradle.category" to "library",
+    "org.gradle.jvm.environment" to "standard-jvm",
+    "org.gradle.libraryelements" to "jar",
+    "org.gradle.usage" to "java-api",
+    "org.jetbrains.kotlin.platform.type" to "jvm",
+)
+val kmpMetadataVariantAttributes = mapOf(
+    "org.gradle.category" to "library",
+    "org.gradle.jvm.environment" to "non-jvm",
+    "org.gradle.libraryelements" to "jar",
+    "org.gradle.usage" to "kotlin-metadata",
+    "org.jetbrains.kotlin.platform.type" to "common",
+)
+val releaseStatus = mapOf(
+    "org.gradle.status" to "release",
+)
+
+// We only emit packing in secondary variants which are not published?
+val nonPacked = mapOf(
+    "org.jetbrains.kotlin.klib.packaging" to "non-packed",
+)
+val jarArtifact = mapOf(
+    "artifactType" to "jar",
+)
+val uklibArtifact = mapOf(
+    "artifactType" to "uklib",
+)
+val platformIosArm64Attributes = mapOf(
+    "artifactType" to "org.jetbrains.kotlin.klib",
+    "org.gradle.category" to "library",
+    "org.gradle.jvm.environment" to "non-jvm",
+    "org.gradle.usage" to "kotlin-api",
+    "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+    "org.jetbrains.kotlin.native.target" to "ios_arm64",
+    "org.jetbrains.kotlin.platform.type" to "native",
+)
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibDependencyDeclarationViolations.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibDependencyDeclarationViolations.kt
index 13b6a50..6ac4ae9 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibDependencyDeclarationViolations.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibDependencyDeclarationViolations.kt
@@ -176,6 +176,95 @@
         }
     }
 
+    @Test
+    fun `dependency specification validation - different compilation scopes - don't trigger violation`() {
+        runTest(
+            { emptySet() }
+        ) {
+            jvm()
+            js()
+
+            // Scopes don't matter because we only care about that all compilations see the same set of dependencies
+            sourceSets.commonMain.dependencies {
+                implementation("a:common:1.0")
+            }
+            sourceSets.jvmMain.dependencies {
+                compileOnly("a:common:1.0")
+            }
+            sourceSets.jsMain.dependencies {
+                api("a:common:1.0")
+            }
+        }
+    }
+
+    @Test
+    fun `dependency specification validation - runtime scope - isn't validated`() {
+        runTest(
+            { emptySet() }
+        ) {
+            jvm()
+            js()
+
+            // We probably don't care about runtime dependencies, so those can be whatever
+            sourceSets.commonMain.dependencies {
+                implementation("a:common:1.0")
+            }
+            sourceSets.jvmMain.dependencies {
+                runtimeOnly("a:runtime_only:1.0")
+            }
+        }
+    }
+
+    @Test
+    fun `dependency specification validation - test compilation dependencies - are not validated`() {
+        runTest(
+            { emptySet() }
+        ) {
+            jvm()
+            js()
+
+            // We don't validate test compilations at all
+            sourceSets.commonMain.dependencies {
+                implementation("a:common:1.0")
+            }
+            sourceSets.commonTest.dependencies {
+                implementation("a:common_test:1.0")
+            }
+            sourceSets.jvmTest.dependencies {
+                implementation("a:jvm_test:1.0")
+            }
+        }
+    }
+
+    @Test
+    fun `dependency specification validation - npm dependencies`() {
+        runTest(
+            { emptySet() }
+        ) {
+            jvm()
+            js()
+
+            sourceSets.jsMain.dependencies {
+                implementation(npm("mocha", "*"))
+            }
+        }
+    }
+
+    @Test
+    fun `dependency specification validation - stdlib and dom dependencies - are not validated`() {
+        runTest(
+            { emptySet() }
+        ) {
+            jvm()
+            js()
+
+            sourceSets.jsMain.dependencies {
+                implementation("")
+            }
+        }
+    }
+
+
     private fun violation(
         configuration: Configuration,
         uniqueDependencies: Set<Dependency>,
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibFromKGPFragmentsTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibFromKGPFragmentsTests.kt
index d2508f6..0314ab1 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibFromKGPFragmentsTests.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibFromKGPFragmentsTests.kt
@@ -11,8 +11,10 @@
 import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
 import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.ERROR
 import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnostic.Severity.WARNING
+import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
 import org.jetbrains.kotlin.gradle.plugin.mpp.external.createCompilation
 import org.jetbrains.kotlin.gradle.plugin.mpp.external.createExternalKotlinTarget
+import org.jetbrains.kotlin.gradle.plugin.mpp.internal
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.UklibFragment
 import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.publication.validateKgpModelIsUklibCompliantAndCreateKgpFragments
 import org.jetbrains.kotlin.gradle.util.*
@@ -282,6 +284,58 @@
         }.evaluate().assertNoDiagnostics()
     }
 
+    @Test
+    fun `project configuration with enabled uklib publication - source set dependencies`() {
+        val p = buildProjectWithMPP(
+            preApplyCode = {
+                publishUklib()
+            }
+        ) {
+            kotlin {
+                sourceSets.commonMain.get().dependencies {
+                    implementation("foo:bar:1")
+                }
+                iosArm64()
+            }
+        }.evaluate()
+        println(p)
+//            .multiplatformExtension.iosArm64().internal
+//            .compilations
+//            .getByName("main").internal.configurations.compileDependencyConfiguration.dependencies
+    }
+
+    @Test
+    fun `underrefinmenet`() {
+        val p = buildProjectWithMPP(
+            preApplyCode = {
+                publishUklib()
+            }
+        ) {
+            kotlin {
+                iosArm64()
+                iosX64()
+                jvm()
+
+                applyHierarchyTemplate {
+                    group("iosAndJvm") {
+                        withIosArm64()
+                        withIosX64()
+                        withJvm()
+                    }
+                    group("onlyIos") {
+                        withIosArm64()
+                        withIosX64()
+                    }
+                }
+            }
+
+        }.evaluate()
+        println(p)
+//            .multiplatformExtension.iosArm64().internal
+//            .compilations
+//            .getByName("main").internal.configurations.compileDependencyConfiguration.dependencies
+    }
+
     private data class TestFragment(
         val identifier: String,
         // FIXME: Test transitive refinees
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionTests.kt
index 933dac5..e35cf16 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionTests.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionTests.kt
@@ -6,18 +6,14 @@
 package org.jetbrains.kotlin.gradle.unitTests.uklibs
 
 import org.gradle.api.Project
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.attributes.Attribute
 import org.gradle.kotlin.dsl.maven
 import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
-import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.UklibResolutionStrategy
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.KmpResolutionStrategy
 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
 import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
 import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
 import org.jetbrains.kotlin.gradle.plugin.sources.internal
 import org.jetbrains.kotlin.gradle.util.*
-import org.jetbrains.kotlin.gradle.utils.projectPathOrNull
-import org.jetbrains.kotlin.utils.keysToMap
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
@@ -26,7 +22,7 @@
 
     @Test
     fun `uklib resolution - from direct pom dependency with uklib packaging`() {
-        val consumer = consumer(UklibResolutionStrategy.ResolveUklibsInMavenComponents) {
+        val consumer = consumer(KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently) {
             jvm()
             iosArm64()
             iosX64()
@@ -61,7 +57,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + uklibTransformationMetadataAttributes)
+                    artifacts=mutableListOf(jvmApiAttributes + uklibTransformationMetadataAttributes)
                 ),
             ),
             metadataCompilationVariants
@@ -75,7 +71,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + uklibTransformationIosArm64Attributes)
+                    artifacts=mutableListOf(jvmApiAttributes + uklibTransformationIosArm64Attributes)
                 ),
             ),
             iosArm64CompilationVariants
@@ -89,7 +85,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + uklibTransformationJvmAttributes)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + uklibTransformationJvmAttributes)
                 ),
             ),
             jvmRuntimeVariants
@@ -103,7 +99,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + uklibTransformationJsAttributes)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + uklibTransformationJsAttributes)
                 ),
             ),
             jsRuntimeVariants
@@ -117,7 +113,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + uklibTransformationWasmJsAttributes)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + uklibTransformationWasmJsAttributes)
                 ),
             ),
             wasmJsVariants
@@ -131,7 +127,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + uklibTransformationWasmWasiAttributes)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + uklibTransformationWasmWasiAttributes)
                 ),
             ),
             wasmWasiVariants
@@ -140,7 +136,7 @@
 
     @Test
     fun `uklib resolution - from direct pom dependency with uklib packaging points to untrasformed uklib - when uklibs are not allowed to resolve`() {
-        val consumer = consumer(UklibResolutionStrategy.IgnoreUklibs) {
+        val consumer = consumer(KmpResolutionStrategy.StandardKMPResolution) {
             jvm()
             iosArm64()
             iosX64()
@@ -174,7 +170,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + uklibArtifact)
+                    artifacts=mutableListOf(jvmApiAttributes + uklibArtifact)
                 ),
             ),
             metadataCompilationVariants
@@ -188,7 +184,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + uklibArtifact)
+                    artifacts=mutableListOf(jvmApiAttributes + uklibArtifact)
                 ),
             ),
             iosArm64CompilationVariants
@@ -202,7 +198,7 @@
                 ),
                 "foo.bar:pure-maven-uklib:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + uklibArtifact)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + uklibArtifact)
                 ),
             ),
             jvmRuntimeVariants
@@ -212,7 +208,7 @@
     // consumer <- pure jvm <- uklib <- PSM-only
     @Test
     fun `uklib resolution - from transitive uklib dependency`() {
-        val consumer = consumer(UklibResolutionStrategy.ResolveUklibsInMavenComponents) {
+        val consumer = consumer(KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently) {
             jvm()
             iosArm64()
             iosX64()
@@ -240,15 +236,15 @@
                 ),
                 "foo.bar:pure-maven-jvm-with-trasitive-uklib-dependency:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + jarArtifact)
+                    artifacts=mutableListOf(jvmApiAttributes + jarArtifact)
                 ),
                 "foo.bar:pure-maven-uklib-with-transitive-non-uklib-dependency:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + uklibTransformationMetadataAttributes)
+                    artifacts=mutableListOf(jvmApiAttributes + uklibTransformationMetadataAttributes)
                 ),
                 "foo.bar:uklib-maven-gradle-packaging:1.0" to ResolvedComponentWithArtifacts(
                     configuration="metadataApiElements",
-                    artifacts=mutableListOf(metadataVariantAttributes + releaseStatus)
+                    artifacts=mutableListOf(kmpMetadataVariantAttributes + releaseStatus)
                 ),
             ),
             metadataCompilationVariants
@@ -262,11 +258,11 @@
                 ),
                 "foo.bar:pure-maven-jvm-with-trasitive-uklib-dependency:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + jarArtifact)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + jarArtifact)
                 ),
                 "foo.bar:pure-maven-uklib-with-transitive-non-uklib-dependency:1.0" to ResolvedComponentWithArtifacts(
                     configuration="runtime",
-                    artifacts=mutableListOf(jvmPomRuntimeAttributes + uklibTransformationJvmAttributes)
+                    artifacts=mutableListOf(jvmRuntimeAttributes + uklibTransformationJvmAttributes)
                 ),
                 "foo.bar:uklib-maven-gradle-packaging:1.0" to ResolvedComponentWithArtifacts(
                     configuration="jvmRuntimeElements-published",
@@ -274,7 +270,7 @@
                 ),
                 "foo.bar:uklib-maven-gradle-packaging-jvm:1.0" to ResolvedComponentWithArtifacts(
                     configuration="jvmRuntimeElements-published",
-                    artifacts=mutableListOf(platformJvmVariantAttributes + releaseStatus)
+                    artifacts=mutableListOf(kmpJvmRuntimeVariantAttributes + releaseStatus)
                 ),
             ),
             jvmRuntimeVariants
@@ -288,11 +284,11 @@
                 ),
                 "foo.bar:pure-maven-jvm-with-trasitive-uklib-dependency:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + jarArtifact)
+                    artifacts=mutableListOf(jvmApiAttributes + jarArtifact)
                 ),
                 "foo.bar:pure-maven-uklib-with-transitive-non-uklib-dependency:1.0" to ResolvedComponentWithArtifacts(
                     configuration="compile",
-                    artifacts=mutableListOf(jvmPomApiAttributes + uklibTransformationIosArm64Attributes)
+                    artifacts=mutableListOf(jvmApiAttributes + uklibTransformationIosArm64Attributes)
                 ),
                 "foo.bar:uklib-maven-gradle-packaging:1.0" to ResolvedComponentWithArtifacts(
                     configuration="iosArm64ApiElements-published",
@@ -327,7 +323,7 @@
     }
 
     private fun consumer(
-        strategy: UklibResolutionStrategy,
+        strategy: KmpResolutionStrategy,
         configure: KotlinMultiplatformExtension.() -> Unit,
     ): Project {
         return buildProjectWithMPP(
@@ -347,167 +343,4 @@
             repositories.maven(javaClass.getResource("/dependenciesResolution/UklibTests/repo")!!)
         }.evaluate()
     }
-
-    private val uklibTransformationIosArm64Attributes = mapOf(
-        "artifactType" to "uklib",
-        "org.jetbrains.kotlin.uklibView" to "ios_arm64",
-        "org.jetbrains.kotlin.uklibState" to "decompressed",
-    )
-
-    private val uklibTransformationJvmAttributes = mapOf(
-        "artifactType" to "uklib",
-        "org.jetbrains.kotlin.uklibView" to "jvm",
-        "org.jetbrains.kotlin.uklibState" to "decompressed",
-    )
-
-    private val uklibTransformationMetadataAttributes = mapOf(
-        "artifactType" to "uklib",
-        "org.jetbrains.kotlin.uklibView" to "whole_uklib",
-        "org.jetbrains.kotlin.uklibState" to "decompressed",
-    )
-
-    private val uklibTransformationJsAttributes = mapOf(
-        "artifactType" to "uklib",
-        "org.jetbrains.kotlin.uklibView" to "js_ir",
-        "org.jetbrains.kotlin.uklibState" to "decompressed",
-    )
-
-    private val uklibTransformationWasmJsAttributes = mapOf(
-        "artifactType" to "uklib",
-        "org.jetbrains.kotlin.uklibView" to "wasm_js",
-        "org.jetbrains.kotlin.uklibState" to "decompressed",
-    )
-
-    private val uklibTransformationWasmWasiAttributes = mapOf(
-        "artifactType" to "uklib",
-        "org.jetbrains.kotlin.uklibView" to "wasm_wasi",
-        "org.jetbrains.kotlin.uklibState" to "decompressed",
-    )
-
-    private val uklibVariantAttributes = mapOf(
-        "org.gradle.category" to "library",
-        "org.gradle.jvm.environment" to "???",
-        "org.gradle.usage" to "kotlin-uklib",
-        "org.jetbrains.kotlin.klib.packaging" to "packed",
-        "org.jetbrains.kotlin.native.target" to "???",
-        "org.jetbrains.kotlin.platform.type" to "unknown",
-    )
-
-    private val jvmPomRuntimeAttributes = mapOf(
-        "org.gradle.category" to "library",
-        "org.gradle.libraryelements" to "jar",
-        "org.gradle.status" to "release",
-        "org.gradle.usage" to "java-runtime",
-    )
-
-    private val jvmPomApiAttributes = mapOf(
-        "org.gradle.category" to "library",
-        "org.gradle.libraryelements" to "jar",
-        "org.gradle.status" to "release",
-        "org.gradle.usage" to "java-api",
-    )
-
-    private val platformJvmVariantAttributes = mapOf(
-        "artifactType" to "jar",
-        "org.gradle.category" to "library",
-        "org.gradle.jvm.environment" to "standard-jvm",
-        "org.gradle.libraryelements" to "jar",
-        "org.gradle.usage" to "java-runtime",
-        "org.jetbrains.kotlin.platform.type" to "jvm",
-    )
-
-    private val metadataVariantAttributes = mapOf(
-        "artifactType" to "jar",
-        "org.gradle.category" to "library",
-        "org.gradle.jvm.environment" to "non-jvm",
-        "org.gradle.libraryelements" to "jar",
-        "org.gradle.usage" to "kotlin-metadata",
-        "org.jetbrains.kotlin.platform.type" to "common",
-    )
-
-    private val releaseStatus = mapOf(
-        "org.gradle.status" to "release",
-    )
-
-    // We only emit packing in secondary variants which are not published?
-    private val nonPacked = mapOf(
-        "org.jetbrains.kotlin.klib.packaging" to "non-packed",
-    )
-
-    private val jarArtifact = mapOf(
-        "artifactType" to "jar",
-    )
-
-    private val uklibArtifact = mapOf(
-        "artifactType" to "uklib",
-    )
-
-    private val platformIosArm64Attributes = mapOf(
-        "artifactType" to "org.jetbrains.kotlin.klib",
-        "org.gradle.category" to "library",
-        "org.gradle.jvm.environment" to "non-jvm",
-        "org.gradle.usage" to "kotlin-api",
-        "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
-        "org.jetbrains.kotlin.native.target" to "ios_arm64",
-        "org.jetbrains.kotlin.platform.type" to "native",
-    )
-
-    data class ResolvedComponentWithArtifacts(
-        val configuration: String,
-        val artifacts: MutableList<Map<String, String>> = mutableListOf(),
-    )
-
-    private fun Configuration.resolveProjectDependencyComponentsWithArtifacts(): Map<String, ResolvedComponentWithArtifacts> {
-        val artifacts = resolveProjectDependencyVariantsFromArtifacts()
-        val components = resolveProjectDependencyComponents()
-        val componentToArtifacts = LinkedHashMap<String, ResolvedComponentWithArtifacts>()
-        components.forEach { component ->
-            if (componentToArtifacts[component.path] == null) {
-                componentToArtifacts[component.path] = ResolvedComponentWithArtifacts(component.configuration)
-            } else {
-                error("${component} resolved multiple times?")
-            }
-        }
-        artifacts.forEach { artifact ->
-            componentToArtifacts[artifact.path]?.let {
-                it.artifacts.add(artifact.attributes)
-            } ?: error("Missing resolved component for artifact: ${artifact}")
-        }
-        return componentToArtifacts
-    }
-
-    data class ResolvedVariant(
-        val path: String,
-        val attributes: Map<String, String>,
-    )
-
-    private fun Configuration.resolveProjectDependencyVariantsFromArtifacts(): List<ResolvedVariant> {
-        return incoming.artifacts.artifacts
-            .map { artifact ->
-                val uklibAttributes: List<Attribute<*>> = artifact.variant.attributes.keySet()
-                    .sortedBy { it.name }
-                ResolvedVariant(
-                    artifact.variant.owner.projectPathOrNull ?: artifact.variant.owner.displayName,
-                    uklibAttributes.keysToMap {
-                        artifact.variant.attributes.getAttribute(it).toString()
-                    }.mapKeys { it.key.name }
-                )
-            }
-    }
-
-    data class ResolvedComponent(
-        val path: String,
-        val configuration: String,
-    )
-
-    private fun Configuration.resolveProjectDependencyComponents(): List<ResolvedComponent> {
-        return incoming.resolutionResult.allComponents
-            .map { component ->
-                ResolvedComponent(
-                    component.id.projectPathOrNull ?: component.id.displayName,
-                    // Expect a single variant to always be selected?
-                    component.variants.single().displayName
-                )
-            }
-    }
 }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWIPTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWIPTests.kt
new file mode 100644
index 0000000..5d1c9e8
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWIPTests.kt
@@ -0,0 +1,322 @@
+///*
+// * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+// * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+// */
+//
+//package org.jetbrains.kotlin.gradle.unitTests.uklibs
+//
+//import org.gradle.api.Project
+//import org.jetbrains.kotlin.gradle.artifacts.UklibResolutionStrategy
+//import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
+//import org.jetbrains.kotlin.gradle.unitTests.uklibs.UklibResolutionTests.ResolvedComponentWithArtifacts
+//import org.jetbrains.kotlin.gradle.util.*
+//import org.jetbrains.kotlin.gradle.util.setUklibResolutionStrategy
+//import kotlin.reflect.full.memberProperties
+//import kotlin.test.assertEquals
+//
+//class UklibResolutionWIPTests {
+//
+//    // @Test
+//    fun `prefer klib variant`() {
+//        val consumer = mixedCompilationsGraphConsumer(
+//            uklibResolutionStrategy = UklibResolutionStrategy.AllowResolvingUklibs,
+//        )
+//
+//        val iosArm64CompilationDependencies = consumer.multiplatformExtension.iosArm64().compilations.getByName("main")
+//            .configurations.compileDependencyConfiguration
+//        val iosArm64ResolvedVariants = iosArm64CompilationDependencies.resolveProjectDependencyComponentsWithArtifacts()
+//
+//        val jvmRuntimeDependencies = consumer.multiplatformExtension.jvm().compilations.getByName("main")
+//            .configurations.runtimeDependencyConfiguration!!
+//        val jvmResolvedVariants = jvmRuntimeDependencies.resolveProjectDependencyComponentsWithArtifacts()
+//
+//        assertEquals(
+//            mapOf(
+//                ":E_consumes_D" to ResolvedComponentWithArtifacts(
+//                    configuration="jvmRuntimeClasspath",
+//                    artifacts=mutableListOf()
+//                ),
+//                ":D_produces_uklib_consumes_C" to ResolvedComponentWithArtifacts(
+//                    configuration="jvmRuntimeElements",
+//                    artifacts=mutableListOf(platformJvmVariantAttributes)
+//                ),
+//                ":C_produces_only_uklib_consumes_B" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationJvmAttributes)
+//                ),
+//                ":B_produces_only_platform_variant_consumes_A" to ResolvedComponentWithArtifacts(
+//                    configuration="jvmRuntimeElements",
+//                    artifacts=mutableListOf(platformJvmVariantAttributes)
+//                ),
+//                ":A_produces_uklib" to ResolvedComponentWithArtifacts(
+//                    configuration="jvmRuntimeElements",
+//                    artifacts=mutableListOf(platformJvmVariantAttributes),
+//                )
+//            ),
+//            jvmResolvedVariants
+//        )
+//
+//        assertEquals(
+//            mapOf(
+//                ":E_consumes_D" to ResolvedComponentWithArtifacts(
+//                    configuration="iosArm64CompileKlibraries",
+//                    artifacts=mutableListOf()
+//                ),
+//                ":D_produces_uklib_consumes_C" to ResolvedComponentWithArtifacts(
+//                    configuration="iosArm64ApiElements",
+//                    artifacts=mutableListOf(platformIosArm64Attributes + nonPacked)
+//                ),
+//                ":C_produces_only_uklib_consumes_B" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationIosArm64Attributes)
+//                ),
+//                ":B_produces_only_platform_variant_consumes_A" to ResolvedComponentWithArtifacts(
+//                    configuration="iosArm64ApiElements",
+//                    artifacts=mutableListOf(platformIosArm64Attributes + nonPacked)
+//                ),
+//                ":A_produces_uklib" to ResolvedComponentWithArtifacts(
+//                    configuration="iosArm64ApiElements",
+//                    artifacts=mutableListOf(platformIosArm64Attributes + nonPacked),
+//                )
+//            ),
+//            iosArm64ResolvedVariants
+//        )
+//    }
+//
+//    // @Test
+//    fun `prefer uklib variant`() {
+//        val consumer = mixedCompilationsGraphConsumer(
+//            uklibResolutionStrategy = UklibResolutionStrategy.AllowResolvingUklibs,
+//        )
+//
+//        val iosArm64CompilationDependencies = consumer.multiplatformExtension.iosArm64().compilations.getByName("main")
+//            .configurations.compileDependencyConfiguration
+//        val iosArm64ResolvedVariants = iosArm64CompilationDependencies.resolveProjectDependencyComponentsWithArtifacts()
+//
+//        val jvmRuntimeDependencies = consumer.multiplatformExtension.jvm().compilations.getByName("main")
+//            .configurations.runtimeDependencyConfiguration!!
+//        // FIXME: java-api variant doesn't resolve A
+//        val jvmResolvedVariants = jvmRuntimeDependencies.resolveProjectDependencyComponentsWithArtifacts()
+//
+//        assertEquals(
+//            mapOf(
+//                ":E_consumes_D" to ResolvedComponentWithArtifacts(
+//                    configuration="jvmRuntimeClasspath",
+//                    artifacts=mutableListOf()
+//                ),
+//                ":D_produces_uklib_consumes_C" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationJvmAttributes)
+//                ),
+//                ":C_produces_only_uklib_consumes_B" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationJvmAttributes)
+//                ),
+//                ":B_produces_only_platform_variant_consumes_A" to ResolvedComponentWithArtifacts(
+//                    configuration="jvmRuntimeElements",
+//                    artifacts=mutableListOf(platformJvmVariantAttributes)
+//                ),
+//                ":A_produces_uklib" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationJvmAttributes),
+//                )
+//            ),
+//            jvmResolvedVariants
+//        )
+//
+//        assertEquals(
+//            mapOf(
+//                ":E_consumes_D" to ResolvedComponentWithArtifacts(
+//                    configuration="iosArm64CompileKlibraries",
+//                    artifacts=mutableListOf()
+//                ),
+//                ":D_produces_uklib_consumes_C" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationIosArm64Attributes)
+//                ),
+//                ":C_produces_only_uklib_consumes_B" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationIosArm64Attributes)
+//                ),
+//                ":B_produces_only_platform_variant_consumes_A" to ResolvedComponentWithArtifacts(
+//                    configuration="iosArm64ApiElements",
+//                    artifacts=mutableListOf(platformIosArm64Attributes + nonPacked)
+//                ),
+//                ":A_produces_uklib" to ResolvedComponentWithArtifacts(
+//                    configuration="metadataUklibElements",
+//                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationIosArm64Attributes),
+//                )
+//            ),
+//            iosArm64ResolvedVariants
+//        )
+//    }
+//
+//    private val uklibTransformationIosArm64Attributes = mapOf(
+//        "artifactType" to "uklib",
+//        "uklibTargetAttribute" to "ios_arm64",
+//        "uklibState" to "unzipped",
+//    )
+//
+//    private val uklibTransformationJvmAttributes = mapOf(
+//        "artifactType" to "uklib",
+//        "uklibTargetAttribute" to "jvm",
+//        "uklibState" to "unzipped",
+//    )
+//
+//    private val uklibTransformationMetadataAttributes = mapOf(
+//        "artifactType" to "uklib",
+//        "uklibTargetAttribute" to "common",
+//        "uklibState" to "unzipped",
+//    )
+//
+//    private val uklibTransformationJsAttributes = mapOf(
+//        "artifactType" to "uklib",
+//        "uklibTargetAttribute" to "js_ir",
+//        "uklibState" to "unzipped",
+//    )
+//
+//    private val uklibTransformationWasmJsAttributes = mapOf(
+//        "artifactType" to "uklib",
+//        "uklibTargetAttribute" to "wasm_js",
+//        "uklibState" to "unzipped",
+//    )
+//
+//    private val uklibTransformationWasmWasiAttributes = mapOf(
+//        "artifactType" to "uklib",
+//        "uklibTargetAttribute" to "wasm_wasi",
+//        "uklibState" to "unzipped",
+//    )
+//
+//    private val uklibVariantAttributes = mapOf(
+//        "org.gradle.category" to "library",
+//        "org.gradle.jvm.environment" to "???",
+//        "org.gradle.usage" to "kotlin-uklib",
+//        "org.jetbrains.kotlin.klib.packaging" to "packed",
+//        "org.jetbrains.kotlin.native.target" to "???",
+//        "org.jetbrains.kotlin.platform.type" to "unknown",
+//    )
+//
+//    private val jvmPomRuntimeAttributes = mapOf(
+//        "org.gradle.category" to "library",
+//        "org.gradle.libraryelements" to "jar",
+//        "org.gradle.status" to "release",
+//        "org.gradle.usage" to "java-runtime",
+//    )
+//
+//    private val jvmPomApiAttributes = mapOf(
+//        "org.gradle.category" to "library",
+//        "org.gradle.libraryelements" to "jar",
+//        "org.gradle.status" to "release",
+//        "org.gradle.usage" to "java-api",
+//    )
+//
+//    private val platformJvmVariantAttributes = mapOf(
+//        "artifactType" to "jar",
+//        "org.gradle.category" to "library",
+//        "org.gradle.jvm.environment" to "standard-jvm",
+//        "org.gradle.libraryelements" to "jar",
+//        "org.gradle.usage" to "java-runtime",
+//        "org.jetbrains.kotlin.platform.type" to "jvm",
+//    )
+//
+//    private val metadataVariantAttributes = mapOf(
+//        "artifactType" to "jar",
+//        "org.gradle.category" to "library",
+//        "org.gradle.jvm.environment" to "non-jvm",
+//        "org.gradle.libraryelements" to "jar",
+//        "org.gradle.usage" to "kotlin-metadata",
+//        "org.jetbrains.kotlin.platform.type" to "common",
+//    )
+//
+//    private val releaseStatus = mapOf(
+//        "org.gradle.status" to "release",
+//    )
+//
+//    // We only emit packing in secondary variants which are not published?
+//    private val nonPacked = mapOf(
+//        "org.jetbrains.kotlin.klib.packaging" to "non-packed",
+//    )
+//
+//    private val jarArtifact = mapOf(
+//        "artifactType" to "jar",
+//    )
+//
+//    private val uklibArtifact = mapOf(
+//        "artifactType" to "uklib",
+//    )
+//
+//    private val platformIosArm64Attributes = mapOf(
+//        "artifactType" to "org.jetbrains.kotlin.klib",
+//        "org.gradle.category" to "library",
+//        "org.gradle.jvm.environment" to "non-jvm",
+//        "org.gradle.usage" to "kotlin-api",
+//        "org.jetbrains.kotlin.cinteropCommonizerArtifactType" to "klib",
+//        "org.jetbrains.kotlin.native.target" to "ios_arm64",
+//        "org.jetbrains.kotlin.platform.type" to "native",
+//    )
+//
+//
+//    private fun mixedCompilationsGraphConsumer(
+//        uklibResolutionStrategy: UklibResolutionStrategy,
+//    ): Project {
+//        val root = buildProject()
+//        return root.child(
+//            "E_consumes_D",
+//            uklibResolutionStrategy = uklibResolutionStrategy,
+//            consume= root.child(
+//                "D_produces_uklib_consumes_C",
+//                consume = root.child(
+//                    "C_produces_only_uklib_consumes_B",
+//                    disablePlatformComponentReferences = true,
+//                    consume = root.child(
+//                        "B_produces_only_platform_variant_consumes_A",
+//                        publishUklibVariant = false,
+//                        consume = root.child(
+//                            "A_produces_uklib",
+//                            consume = null
+//                        )
+//                    )
+//                )
+//            )
+//        )
+//    }
+//
+//    private fun Project.child(
+//        name: String,
+//        consume: Project?,
+//        publishUklibVariant: Boolean = true,
+//        disablePlatformComponentReferences: Boolean = false,
+//        uklibResolutionStrategy: UklibResolutionStrategy = UklibResolutionStrategy.ResolveOnlyPlatformSpecificVariant,
+//    ): Project {
+//        val parent = this
+//        return buildProjectWithMPP(
+//            preApplyCode = {
+//                if (publishUklibVariant) {
+//                    publishUklib()
+//                }
+//                fakeUklibTransforms()
+//                setUklibResolutionStrategy(uklibResolutionStrategy)
+//                disablePlatformSpecificComponentReferences(disablePlatformComponentReferences)
+//                // Test stdlib in a separate test
+//                enableDefaultStdlibDependency(false)
+//                enableDefaultJsDomApiDependency(false)
+//            },
+//            projectBuilder = {
+//                withParent(parent)
+//                withName(name)
+//            }
+//        ) {
+//            kotlin {
+//                iosArm64()
+//                iosX64()
+//                jvm()
+//
+//                if (consume != null) {
+//                    sourceSets.commonMain.dependencies {
+//                        implementation(project(consume.project.path))
+//                    }
+//                }
+//            }
+//        }.evaluate()
+//    }
+//}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt
new file mode 100644
index 0000000..23005cf
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.unitTests.uklibs
+
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.maven
+import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
+import org.jetbrains.kotlin.gradle.internal.dsl.KotlinMultiplatformSourceSetConventionsImpl.commonMain
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.KmpResolutionStrategy
+import org.jetbrains.kotlin.gradle.plugin.sources.internal
+import org.jetbrains.kotlin.gradle.unitTests.uklibs.GradleMetadataComponent.Variant
+import org.jetbrains.kotlin.gradle.util.*
+import org.jetbrains.kotlin.gradle.util.setUklibResolutionStrategy
+import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
+import org.junit.Rule
+import org.junit.rules.TemporaryFolder
+import kotlin.test.Test
+
+class UklibResolutionTestsWithMockComponents {
+    @get:Rule
+    val tmpDir = TemporaryFolder()
+
+    @Test
+    fun `uklib resolution - resolving pure uklib component`() {
+        val repo = generateMockRepository(
+            tmpDir,
+            listOf(
+                GradleComponent(
+                    GradleMetadataComponent(
+                        component = fooBarGradleComponent,
+                        variants = listOf(
+                            uklibApiVariant,
+                            jvmApiVariant,
+                        ),
+                    ),
+                    fooBarUklibMavenComponent,
+                )
+            )
+        )
+
+        val consumer = uklibConsumer {
+            kotlin {
+                iosArm64()
+                jvm()
+                sourceSets.commonMain.dependencies { implementation("foo:bar:1.0") }
+            }
+            repositories.maven(repo)
+        }
+
+        assertEqualsPP(
+            mapOf(
+                "foo:bar:1.0" to ResolvedComponentWithArtifacts(
+                    configuration="uklibApiElements",
+                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationIosArm64Attributes + releaseStatus)
+                ),
+            ),
+            consumer.multiplatformExtension.iosArm64().compilationResolution(),
+        )
+        assertEqualsPP(
+            mapOf(
+                "foo:bar:1.0" to ResolvedComponentWithArtifacts(
+                    configuration="uklibApiElements",
+                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationJvmAttributes + releaseStatus)
+                ),
+            ),
+            consumer.multiplatformExtension.jvm().compilationResolution(),
+        )
+        assertEqualsPP(
+            mapOf(
+                "foo:bar:1.0" to ResolvedComponentWithArtifacts(
+                    configuration="uklibApiElements",
+                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationMetadataAttributes + releaseStatus)
+                ),
+            ),
+            consumer.multiplatformExtension.sourceSets.commonMain.get().internal.resolvableMetadataConfiguration.resolveProjectDependencyComponentsWithArtifacts(),
+        )
+    }
+
+    @Test
+    fun `uklib resolution - resolving existings kmp publication`() {
+        val repo = generateMockRepository(
+            tmpDir,
+            listOf(
+                GradleComponent(
+                    GradleMetadataComponent(
+                        component = fooBarGradleComponent,
+                        variants = listOf(
+                            kmpMetadataJarVariant,
+                            kmpIosArm64KlibVariant,
+                            kmpJvmApiVariant,
+                        ),
+                    ),
+                    fooBarUklibMavenComponent,
+                )
+            )
+        )
+
+        val consumer = uklibConsumer {
+            kotlin {
+                iosArm64()
+                jvm()
+                sourceSets.commonMain.dependencies { implementation("foo:bar:1.0") }
+            }
+            repositories.maven(repo)
+        }
+
+        assertEqualsPP(
+            mapOf(
+                "foo:bar:1.0" to ResolvedComponentWithArtifacts(
+                    configuration="uklibApiElements",
+                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationIosArm64Attributes + releaseStatus)
+                ),
+            ),
+            consumer.multiplatformExtension.iosArm64().compilationResolution(),
+        )
+        assertEqualsPP(
+            mapOf(
+                "foo:bar:1.0" to ResolvedComponentWithArtifacts(
+                    configuration="uklibApiElements",
+                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationJvmAttributes + releaseStatus)
+                ),
+            ),
+            consumer.multiplatformExtension.jvm().compilationResolution(),
+        )
+        assertEqualsPP(
+            mapOf(
+                "foo:bar:1.0" to ResolvedComponentWithArtifacts(
+                    configuration="uklibApiElements",
+                    artifacts=mutableListOf(uklibVariantAttributes + uklibTransformationMetadataAttributes + releaseStatus)
+                ),
+            ),
+            consumer.multiplatformExtension.sourceSets.commonMain.get().internal.resolvableMetadataConfiguration.resolveProjectDependencyComponentsWithArtifacts(),
+        )
+    }
+
+    private fun uklibConsumer(code: Project.() -> Unit = {}): Project {
+        return buildProjectWithMPP(
+            preApplyCode = {
+                fakeUklibTransforms()
+                setUklibResolutionStrategy(KmpResolutionStrategy.ResolveUklibsAndResolvePSMLeniently)
+                // Test stdlib in a separate test
+                enableDefaultStdlibDependency(false)
+                enableDefaultJsDomApiDependency(false)
+            },
+            code = code,
+        ).evaluate()
+    }
+
+    private val fooBarGradleComponent = GradleMetadataComponent.Component(
+        group = "foo",
+        module = "bar",
+        version = "1.0",
+    )
+    private val fooBarUklibMavenComponent = MavenComponent(
+        "foo", "bar", "1.0",
+        packaging = "uklib",
+        dependencies = listOf(),
+        true,
+    )
+
+    private val uklibApiVariant = Variant(
+        name = "uklibApiElements",
+        attributes = mapOf(
+            "org.gradle.usage" to "kotlin-uklib-api",
+            "org.gradle.category" to "library",
+        ),
+        files = listOf(
+            GradleMetadataComponent.StubVariantFile(
+                artifactId = "bar",
+                version = "1.0",
+                extension = "uklib"
+            )
+        ),
+        dependencies = listOf()
+    )
+
+    private val jvmApiVariant = Variant(
+        name = "jvmApiElements",
+        attributes = jvmApiAttributes,
+        files = listOf(
+            GradleMetadataComponent.StubVariantFile(
+                artifactId = "bar",
+                version = "1.0",
+                extension = "jar"
+            )
+        ),
+        dependencies = listOf()
+    )
+
+    private val aarApiVariant = Variant(
+        name = "jvmApiElements",
+        attributes = jvmApiAttributes,
+        files = listOf(
+            GradleMetadataComponent.StubVariantFile(
+                artifactId = "bar",
+                version = "1.0",
+                extension = "jar"
+            )
+        ),
+        dependencies = listOf()
+    )
+
+    private val kmpMetadataJarVariant = Variant(
+        name = "metadataApiElements",
+        attributes = kmpMetadataVariantAttributes,
+        files = listOf(
+            GradleMetadataComponent.StubVariantFile(
+                artifactId = "bar",
+                version = "1.0",
+                extension = "jar"
+            )
+        ),
+        dependencies = listOf()
+    )
+
+    private val kmpIosArm64KlibVariant = Variant(
+        name = "iosArm64ApiElements-published",
+        attributes = mapOf(
+            "artifactType" to "org.jetbrains.kotlin.klib", // wtf?
+            "org.gradle.category" to "library",
+            "org.gradle.jvm.environment" to "non-jvm",
+            "org.gradle.usage" to "kotlin-api",
+            "org.jetbrains.kotlin.native.target" to "ios_arm64",
+            "org.jetbrains.kotlin.platform.type" to "native",
+        ),
+        files = listOf(
+            GradleMetadataComponent.StubVariantFile(
+                artifactId = "bar",
+                version = "1.0",
+                extension = "klib"
+            )
+        ),
+        dependencies = listOf()
+    )
+
+    private val kmpJvmApiVariant = Variant(
+        name = "jvmApiElements-published",
+        attributes = kmpJvmApiVariantAttributes,
+        files = listOf(
+            GradleMetadataComponent.StubVariantFile(
+                artifactId = "bar",
+                version = "1.0",
+                extension = "jar"
+            )
+        ),
+        dependencies = listOf()
+    )
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt
new file mode 100644
index 0000000..e64fa19
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.unitTests.uklibs
+
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.encodeToJsonElement
+import kotlinx.serialization.json.jsonObject
+import org.junit.rules.TemporaryFolder
+import org.w3c.dom.Document
+import java.io.ByteArrayOutputStream
+import java.io.File
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.OutputKeys
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+
+private val json = Json {
+    encodeDefaults = true
+    prettyPrint = true
+}
+
+class GradleComponent(
+    val module: GradleMetadataComponent,
+    val pom: MavenComponent,
+)
+
+@Serializable
+class GradleMetadataComponent(
+    val formatVersion: String = "1.1",
+    val component: Component,
+    val createdBy: Map<String, Map<String, String>> = mapOf(
+        "gradle" to mapOf(
+            "version" to "8.11.1"
+        )
+    ),
+    val variants: List<Variant>
+) {
+    @Serializable
+    class Component(
+        val group: String,
+        val module: String,
+        val version: String,
+        val attributes: Map<String, String> = mapOf(
+            "org.gradle.status" to "release"
+        ),
+    )
+
+    @Serializable
+    class Variant(
+        val name: String,
+        val attributes: Map<String, String>,
+        val dependencies: List<Component>,
+        val files: List<StubVariantFile> = emptyList(),
+    )
+
+    @Serializable
+    class StubVariantFile(
+        val url: String,
+        val name: String = url,
+        val size: Int = 0,
+    ) {
+        constructor(
+            artifactId: String,
+            version: String,
+            extension: String,
+            classifier: String? = null,
+        ) : this(listOfNotNull(artifactId, version, classifier).joinToString("-") + ".${extension}")
+    }
+
+    @Serializable
+    class Dependency(
+        val group: String,
+        val module: String,
+        val version: Version,
+        val attributes: Map<String, String>? = null,
+    )
+
+    @Serializable
+    class Version(
+        val requires: String,
+    )
+}
+
+class MavenComponent(
+    val groupId: String,
+    val artifactId: String,
+    val version: String,
+    val packaging: String,
+    val dependencies: List<Dependency>,
+    val gradleMetadataMarker: Boolean,
+) {
+    class Dependency(
+        val groupId: String?,
+        val artifactId: String?,
+        val version: String?,
+        val scope: String?,
+    )
+}
+
+fun generateMockRepository(
+    temporaryFolder: TemporaryFolder,
+    gradleComponents: List<GradleComponent> = emptyList(),
+    mavenComponents: List<MavenComponent> = emptyList(),
+): File {
+    val repositoryRoot = temporaryFolder.newFolder()
+    val repository = MockRepository(repositoryRoot)
+    gradleComponents.forEach {
+        repository.addGradleComponent(
+            it.module, it.pom
+        )
+    }
+    mavenComponents.forEach {
+        repository.addMavenComponent(it)
+    }
+    return repositoryRoot
+}
+
+private class MockRepository(
+    private val root: File
+) {
+    fun addGradleComponent(
+        gradleComponent: GradleMetadataComponent,
+        mavenComponent: MavenComponent,
+    ) {
+        val componentRoot = createComponentRoot(mavenComponent)
+        componentRoot.resolve("${mavenComponent.artifactId}-${mavenComponent.version}.pom").writeText(
+            generatePom(mavenComponent)
+        )
+        componentRoot.resolve("${mavenComponent.artifactId}-${mavenComponent.version}.module").writeText(
+            with(json.encodeToJsonElement(gradleComponent)) {
+                // Gradle requires that "formatVersion" field be the first in the module json
+                json.encodeToString(
+                    jsonObject.entries
+                        .sortedBy { (key, _) -> if (key == "formatVersion") 0 else 1 }
+                        .map { it.key to it.value }
+                        .toMap()
+                )
+            }
+        )
+        gradleComponent.variants.forEach { variant ->
+            variant.files.forEach { file ->
+                componentRoot.resolve(file.url).createNewFile()
+            }
+        }
+    }
+
+    fun addMavenComponent(mavenComponent: MavenComponent) {
+        val componentRoot = createComponentRoot(mavenComponent)
+        componentRoot.resolve("${mavenComponent.artifactId}-${mavenComponent.version}.pom").writeText(
+            generatePom(mavenComponent)
+        )
+        componentRoot.resolve("${mavenComponent.artifactId}-${mavenComponent.version}.jar").createNewFile()
+    }
+
+    private fun createComponentRoot(component: MavenComponent): File {
+        val path = component.groupId.split(".") + listOf(
+            component.artifactId,
+            component.version,
+        )
+        val componentRoot = root.resolve(path.joinToString("/"))
+        componentRoot.mkdirs()
+        return componentRoot
+    }
+
+    private fun generatePom(component: MavenComponent): String {
+        val doc: Document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
+
+        doc.appendChild(
+            doc.createElement("project").apply {
+                setAttribute("xmlns", "http://maven.apache.org/POM/4.0.0")
+                setAttribute("xsi:schemaLocation", "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd")
+                setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+                if (component.gradleMetadataMarker) {
+                    appendChild(
+                        doc.createComment("do_not_remove: published-with-gradle-metadata")
+                    )
+                }
+                appendChild(
+                    doc.createElement("modelVersion").apply {
+                        textContent = "4.0.0"
+                    }
+                )
+                appendChild(
+                    doc.createElement("groupId").apply {
+                        textContent = component.groupId
+                    }
+                )
+                appendChild(
+                    doc.createElement("artifactId").apply {
+                        textContent = component.artifactId
+                    }
+                )
+                appendChild(
+                    doc.createElement("version").apply {
+                        textContent = component.version
+                    }
+                )
+                appendChild(
+                    doc.createElement("packaging").apply {
+                        textContent = component.packaging
+                    }
+                )
+                appendChild(
+                    doc.createElement("dependencies").apply {
+                        component.dependencies.forEach { dependency ->
+                            appendChild(
+                                doc.createElement("dependency").apply {
+                                    dependency.groupId?.let {
+                                        appendChild(
+                                            doc.createElement("groupId").apply {
+                                                textContent = it
+                                            }
+                                        )
+                                    }
+                                    dependency.artifactId?.let {
+                                        appendChild(
+                                            doc.createElement("artifactId").apply {
+                                                textContent = it
+                                            }
+                                        )
+                                    }
+                                    dependency.version?.let {
+                                        appendChild(
+                                            doc.createElement("version").apply {
+                                                textContent = it
+                                            }
+                                        )
+                                    }
+                                    dependency.scope?.let {
+                                        appendChild(
+                                            doc.createElement("scope").apply {
+                                                textContent = it
+                                            }
+                                        )
+                                    }
+                                }
+                            )
+                        }
+                    }
+                )
+            }
+        )
+
+        return ByteArrayOutputStream().apply {
+            TransformerFactory.newInstance().newTransformer().apply {
+                setOutputProperty(OutputKeys.INDENT, "yes")
+                setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
+            }.transform(DOMSource(doc), StreamResult(this))
+        }.toString()
+    }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt
index 0fc0b20..9876175 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt
@@ -13,7 +13,7 @@
 import org.gradle.api.plugins.ExtraPropertiesExtension
 import org.gradle.testfixtures.ProjectBuilder
 import org.gradle.testing.base.TestingExtension
-import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.UklibResolutionStrategy
+import org.jetbrains.kotlin.gradle.plugin.mpp.uklibs.consumption.KmpResolutionStrategy
 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
 import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
 import org.jetbrains.kotlin.gradle.plugin.*
@@ -143,8 +143,8 @@
     propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_NATIVE_ENABLE_KLIBS_CROSSCOMPILATION, enabled.toString())
 }
 
-internal fun Project.setUklibResolutionStrategy(strategy: UklibResolutionStrategy) {
-    propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_KMP_UKLIB_RESOLUTION_STRATEGY, strategy.propertyName)
+internal fun Project.setUklibResolutionStrategy(strategy: KmpResolutionStrategy) {
+    propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_KMP_RESOLUTION_STRATEGY, strategy.propertyName)
 }
 
 fun Project.fakeUklibTransforms() {