Difference between runtime and runtimeClasspath configurations

I have spent several hours trying to create custom sourceset and depend on them, but something always tripped up in the configurations, and I couldn’t spot it. Now I found it: the subtle difference between runtime and runtimeClasspath, where the latter apparently somehow contains the sourceset outputs, and since default extends from it it also contains them.

Now I tried to find out how these differences are declared, to potentially make use of that in custom configurations. I tried to print all sorts of properties of both tasks, even attempted to look into the gradle source code, but the only thing I found that seemed noticeably different was attributes:

runtimeClasspath
attributes: {org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime, org.jetbrains.kotlin.platform.type=jvm}
extensFrom: [configuration ':plugin:runtimeOnly', configuration ':plugin:runtime', configuration ':plugin:implementation']
runtime
attributes: {org.jetbrains.kotlin.localToProject=local to :plugin, org.jetbrains.kotlin.platform.type=jvm}
extensFrom: [configuration ':plugin:compile']

runtimeClasspath also extends from some other configurations, but as I selectively tried depending on them, none seemed to contain the compiled sources, so it must be somehow declared in runtimeClasspath itself.

I read through https://docs.gradle.org/current/userguide/java_plugin.html#tab:configurations but that only gives a rather basic overview.

Now it’s getting even weirder:
I created a sourceset client and, from the other project, depend on the consumable client configuration which extends from clientRuntimeClasspath. Yet, compilation doesn’t work, and if I print the classpath of compileKotlin it contains only the outputs of the main sourceset!
What the heck? Is gradle doing witchcraft behind the scenes?

Hello, anyone present?