gradle-multimodule — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited gradle-multimodule (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 editing the SKaiNET multi-module Gradle build. The project is a Gradle composite build: build-logic/ is included via includeBuild and contributes convention plugins; every module under skainet-*/ is included from settings.gradle.kts; all dependency coordinates resolve through gradle/libs.versions.toml.
build.gradle.kts, settings.gradle.kts, or *.gradle.kts under build-logic/.gradle/libs.versions.toml (versions, libraries, plugins, bundles).kmp.kotlin.skainet-testing owns assertion APIs and source-set placement for tests.build.gradle.kts MUST go through libs.versions.<x>, libs.<library>, or libs.plugins.<plugin>. Hard-coded version strings ("1.10.2", version = "2.3.21") MUST NOT appear in module build scripts.id("...") without a version is the pattern for the in-tree convention plugins (sk.ainet.dokka, sk.ainet.multiplatform, sk.ainet.documentation, sk.ainet.npm-pins, sk.ainet.maven-pins, sk.ainet.transformers.bom-coverage) — local plugins have no version to track. id("...") version "..." with a literal version is reserved for build-logic/convention/build.gradle.kts itself.skainet-foo module: (a) create skainet-foo/build.gradle.kts, (b) add include("skainet-foo") (or the nested form) to settings.gradle.kts, (c) add the module's own gradle.properties with POM_ARTIFACT_ID and POM_NAME — without it the publication has no POM name and never reaches Maven Central (this bit skainet-compile-minerva once), (d) apply alias(libs.plugins.vanniktech.mavenPublish). BOM membership is automatic: the sk.ainet.transformers.bom-coverage plugin on skainet-bom adds every sibling that applies the publish plugin as an api constraint; to keep a published module OUT of the BOM, add its path to bomCoverage.excludePublished in skainet-bom/build.gradle.kts.id("sk.ainet.dokka"), not by configuring Dokka directly. Convention plugins live in build-logic/convention/src/main/kotlin/../gradlew :module:apiDump and commit the diff (see kotlin skill, api-stability reference).build.gradle.kts requires JDK 21+, sets JvmTarget.JVM_21 on every Kotlin JVM target and options.release = 21 for Java sources — do not re-declare that per module. Android compilations are the exception: they target JvmTarget.JVM_11 (set in the android { } block, or via skainet { androidJvmTarget } under the sk.ainet.multiplatform plugin; the skainet-io family explicitly ships JVM_1_8).api(...) only when the dependency's types appear in a module's public Kotlin signatures. Default to implementation(...). KSP-generated source goes through add("kspCommonMainMetadata", project(":skainet-...:...-ksp-processor")).skainet-lang, skainet-data, skainet-io, skainet-backends, skainet-compile, skainet-models, skainet-pipeline, skainet-apps, skainet-test).build.gradle.kts that mirrors the closest sibling. Prefer the convention-plugin set (id("sk.ainet.multiplatform"), androidMultiplatformLibrary for Android, vanniktech.mavenPublish, binary.compatibility.validator, sk.ainet.dokka, optionally ksp, kotlinx-benchmark) plus a skainet { namespace = "..." } block.include("skainet-<group>:<module>") to settings.gradle.kts in the matching // ====== <GROUP> section.gradle.properties with POM_ARTIFACT_ID / POM_NAME (published modules), and skainet.targets= only when diverging from the default target set.vanniktech.mavenPublish is applied../gradlew :skainet-<group>:<module>:assemble to validate the wiring../gradlew :skainet-<group>:<module>:apiDump and commit the dump.Module `build.gradle.kts` — convention-plugin form (preferred for new modules):
plugins {
id("sk.ainet.multiplatform")
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.vanniktech.mavenPublish)
alias(libs.plugins.binary.compatibility.validator)
id("sk.ainet.dokka")
}
// Targets, explicitApi() and kotlin-test in commonTest come from sk.ainet.multiplatform.
skainet {
namespace = "sk.ainet.pipeline"
}
// from: SKaiNET/skainet-pipeline/build.gradle.kts:1-15Module `build.gradle.kts` — hand-rolled KMP library with KSP and Dokka (older modules):
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.vanniktech.mavenPublish)
alias(libs.plugins.binary.compatibility.validator)
alias(libs.plugins.ksp)
id("sk.ainet.dokka")
id("org.jetbrains.kotlinx.benchmark")
}
kotlin {
explicitApi()
// ... target list goes here — see kmp skill ...
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:4-82Catalog entries — every coordinate routed through `libs.versions.toml`:
[versions]
kotlin = "2.4.20"
ksp = "2.3.10"
dokka = "2.2.0"
kotest = "6.2.5"
kover = "0.9.9"
binaryCompatibilityValidator = "0.18.2"
[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotest-runner-junit5 = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" }
[plugins]
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
skainet-docs = { id = "sk.ainet.documentation" }
skainet-multiplatform = { id = "sk.ainet.multiplatform" }
skainet-npmPins = { id = "sk.ainet.npm-pins" }
// excerpt — values drift; SKaiNET/gradle/libs.versions.toml is the source of truth
// (it also holds the npm security pins forced into the kotlin-js-store lockfiles)`settings.gradle.kts` — module registration, grouped by area:
includeBuild("build-logic")
// ====== LANG
include("skainet-lang:skainet-lang-core")
include("skainet-lang:skainet-lang-models")
include("skainet-lang:skainet-lang-ksp-annotations")
include("skainet-lang:skainet-lang-ksp-processor")
include("skainet-lang:skainet-lang-dag")
// ====== DATA
include("skainet-data:skainet-data-api")
include("skainet-data:skainet-data-source")
include("skainet-data:skainet-data-transform")
include("skainet-data:skainet-data-simple")
include("skainet-data:skainet-data-media")
// ====== TEST
include("skainet-test:skainet-test-groundtruth")
include("skainet-test:skainet-test-java")
// from: SKaiNET/settings.gradle.kts:21-78 (abridged — the full file also includes the
// COMPILE, BACKENDS, BENCHMARKS, PIPELINE, IO, models, BOM, APPS and DOCS sections)expect/actual placement — see ../kmp/SKILL.md.../kotlin/SKILL.md.../skainet-testing/SKILL.md.// WRONG — hard-coded coordinate / version
implementation("io.kotest:kotest-runner-junit5:6.2.5")// RIGHT — catalog reference
implementation(libs.kotest.runner.junit5)// WRONG — applying Dokka by id
plugins { id("org.jetbrains.dokka") version "2.2.0" }// RIGHT — apply the convention plugin (it configures Dokka)
plugins { id("sk.ainet.dokka") }// WRONG — adding a new module without registering it
// (skainet-io/skainet-io-newformat/build.gradle.kts created, but settings.gradle.kts unchanged)// RIGHT — also edit settings.gradle.kts AND add the module's gradle.properties
// (POM_ARTIFACT_ID / POM_NAME) in the same change; the BOM picks it up automatically
include("skainet-io:skainet-io-newformat") // in settings.gradle.ktsreferences/catalog-aliases.md — version, library, and plugin aliases pulled from libs.versions.toml.references/convention-plugins.md — the full sk.ainet.* convention-plugin set (multiplatform, dokka, documentation, npm-pins, maven-pins, bom-coverage) and how to add a new one.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.