kmp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited kmp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Rules for configuring Kotlin Multiplatform targets and source-set hierarchies in SKaiNET. Pure-logic code lives in commonMain and runs on every target; platform-specific implementations are confined to the narrowest source-set that needs them.
commonMain / jvmMain / a native target / a JS or WASM target.expect / actual declarations.dependencies { } blocks per source set.gradle-multimodule.kotlin.jvmMain/sk.ainet.java) — coordinate with skainet-java-interop.id("sk.ainet.multiplatform") (plus alias(libs.plugins.androidMultiplatformLibrary) to opt into Android) and declare skainet { namespace = "sk.ainet.<area>" }. The default target set is jvm, js { browser() }, wasmJs { browser() }, wasmWasi { nodejs() }, apple (iosArm64, iosSimulatorArm64, macosArm64) and linux (linuxX64, linuxArm64); a module that differs sets the skainet.targets Gradle property in its own gradle.properties (comma-separated list; androidNative adds androidNativeArm32/androidNativeArm64 for vendor-native backends; none means the module declares every target itself). The plugin also applies explicitApi() and wires kotlin-test into commonTest (both switchable in skainet { }). Older modules such as skainet-lang-core still write the same canonical list by hand:jvm()android { namespace = "sk.ainet.<area>"; compileSdk = libs.versions.android.compileSdk.get().toInt(); minSdk = libs.versions.android.minSdk.get().toInt(); compilerOptions { jvmTarget.set(JvmTarget.JVM_11) } }iosArm64(), iosSimulatorArm64()macosArm64()linuxX64(), linuxArm64()androidNativeArm32(), androidNativeArm64() (vendor-native backends)js { browser() }@OptIn(ExperimentalWasmDsl::class) wasmJs { browser() }, @OptIn(ExperimentalWasmDsl::class) wasmWasi { nodejs() }jvmMain for java.io, iosArm64Main for an iOS-specific call, etc.commonMain cannot resolve.commonTest source set; in practice the library modules' jvmTest sets use kotlin.test too, and Kotest (runner + assertions + property) appears only in the skainet-apps/skainet-grayscale-cli JVM test suite.commonMain.dependencies { }, jvmMain.dependencies { }), or the sourceSets { commonMain { dependencies { ... } } } form. Don't add dependencies to the bare dependencies { } block at the top level of a KMP module — that's a JVM-only Gradle pattern.implementation(...). The KSP annotations module is a deliberate api(...) because KSP-generated code references those annotations from commonMain.commonMain.kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin"). The tasks.configureEach { … dependsOn("kspCommonMainKotlinMetadata") } block at the bottom of the build script is required — copy it verbatim from skainet-lang-core/build.gradle.kts:85-90 when KSP is involved.iosMain aggregating iosArm64Main + iosSimulatorArm64Main; nativeMain aggregating all native targets) only when at least two siblings actually share code. For code shared between the JVM and Android compilations only (e.g. java.nio mmap storage), the project pattern is a plain shared source directory — src/jvmAndroidMain/kotlin added via kotlin.srcDir(...) to both jvmMain and androidMain — not an intermediate source set, so each compilation keeps its full platform classpath (see skainet-lang-core/build.gradle.kts:71-76, #921).id("sk.ainet.multiplatform") and only declare skainet.targets in the module's gradle.properties if it must diverge from the default set (divergence MUST be justified in the change description). When editing an older hand-rolled module, keep its existing target list in sync with the canonical set.commonMain.jvmMain, iosArm64Main, wasmJsMain).expect in commonMain, actual in each platform source set that the module targets.commonMain.dependencies { }, etc.).commonTest for cross-target, jvmTest for JVM-only fixtures) — kotlin.test in both../gradlew :module:assemble to validate every target compiles. If a Native target fails, the source set probably leaked a JVM API — move it to jvmMain.Convention-plugin module (preferred for new modules):
plugins {
id("sk.ainet.multiplatform")
alias(libs.plugins.androidMultiplatformLibrary) // opt into Android
alias(libs.plugins.vanniktech.mavenPublish)
alias(libs.plugins.binary.compatibility.validator)
id("sk.ainet.dokka")
}
// Default target set (jvm, js, wasmJs, wasmWasi, apple, linux + Android from the
// AGP plugin above), explicitApi() and kotlin-test in commonTest all come from
// sk.ainet.multiplatform.
skainet {
namespace = "sk.ainet.pipeline"
}
// from: SKaiNET/skainet-pipeline/build.gradle.kts:1-15Full hand-rolled target list with explicit-API mode (older modules):
kotlin {
explicitApi()
android {
namespace = "sk.ainet.lang.core"
compileSdk = libs.versions.android.compileSdk.get().toInt()
minSdk = libs.versions.android.minSdk.get().toInt()
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}
iosArm64()
iosSimulatorArm64()
macosArm64()
linuxX64()
linuxArm64()
androidNativeArm32()
androidNativeArm64()
jvm()
js {
browser()
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
}
@OptIn(ExperimentalWasmDsl::class)
wasmWasi {
nodejs()
}
// ... source sets ...
}
// from: SKaiNET/skainet-lang/skainet-lang-core/build.gradle.kts:14-50Per-source-set dependencies and KSP-generated source folder:
sourceSets {
commonMain {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
dependencies {
api(project(":skainet-lang:skainet-lang-ksp-annotations"))
}
}
jvmMain.dependencies {
implementation(libs.kotlinx.benchmark.runtime)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
// from: SKaiNET/skainet-lang/skainet-lang-core/build.gradle.kts:52-81 (abridged — the
// full block also adds the shared src/jvmAndroidMain directory to jvmMain and androidMain)KSP wiring required when `commonMain` consumes generated code:
tasks.configureEach {
if (name != "kspCommonMainKotlinMetadata" &&
(name.startsWith("compileKotlin") || name.startsWith("ksp") || name.contains("ourcesJar"))) {
dependsOn("kspCommonMainKotlinMetadata")
}
}
dependencies {
add("kspCommonMainMetadata", project(":skainet-lang:skainet-lang-ksp-processor"))
}
// from: SKaiNET/skainet-lang/skainet-lang-core/build.gradle.kts:85-96libs.plugins.kotlinMultiplatform, libs.kotlinx.io.core) and module registration — see ../gradle-multimodule/SKILL.md.../kotlin/SKILL.md.jvmMain under sk/ainet/java/ — see ../skainet-java-interop/SKILL.md.// WRONG — top-level dependencies block on a KMP module
dependencies {
implementation(libs.kotlinx.io.core)
}// RIGHT — per-source-set
sourceSets {
commonMain.dependencies { implementation(libs.kotlinx.io.core) }
}// WRONG — `actual` in commonMain
// commonMain/.../FileLoader.kt
public actual fun loadModelFile(path: String): ByteArray = TODO() // commonMain has no platform API// RIGHT — expect in commonMain, actual in jvmMain
// commonMain/.../FileLoader.kt
public expect fun loadModelFile(path: String): ByteArray
// jvmMain/.../FileLoader.kt
public actual fun loadModelFile(path: String): ByteArray = java.io.File(path).readBytes()// WRONG — Kotest in commonTest
// commonTest/.../FooSpec.kt
import io.kotest.core.spec.style.StringSpec // Kotest runner is JVM-only// RIGHT — kotlin.test in commonTest and jvmTest alike
// commonTest/.../FooTest.kt (and jvmTest, in library modules)
import kotlin.test.Testreferences/target-matrix.md — every KMP target SKaiNET ships, what it's used for, and the per-target source-set name.references/sourceset-rules.md — the commonMain → platform source-set hierarchy and expect/actual placement decision tree.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.