From 43d63db5f52bfeeec5e4b7f5ebaabf0eeebc4b50 Mon Sep 17 00:00:00 2001 From: Michal Harakal Date: Mon, 25 May 2026 14:29:11 +0200 Subject: [PATCH] make the catalog BOM-only: versionless skainet-* aliases + platform(:llm-bom) in every consumer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the last big "Deferred" item from #144. Until now, every skainet-* alias in gradle/libs.versions.toml pinned a version through `version.ref = "skainet"`, so the BOM that :llm-bom re-exports was only exercised by external consumers — internal builds resolved against the catalog. This change inverts that: the catalog supplies coordinates only, and the BOM is the single source of versions for every internal build. - gradle/libs.versions.toml: strip `version.ref = "skainet"` from all eleven `skainet-*` library aliases. The single `[versions] skainet` entry stays at the top — it still drives the `platform("sk.ainet:skainet-bom:${libs.versions.skainet.get()}")` reference in `llm-bom/build.gradle.kts`, so an engine bump is still a one-line edit. - Every consumer module gains `implementation(project.dependencies.platform(project(":llm-bom")))` in each source set that pulls a skainet-* artifact. The KMP idiom uses `project.dependencies.platform(...)` instead of the bare `platform(...)` accessor — the latter is deprecated for removal in Kotlin 2.3 and now fails source-set DSL compilation. JVM-only modules (llm-providers, llm-apps/*) keep the simpler `platform(project(":llm-bom"))` form. Touched modules (17): llm-core (commonMain + jvmTest) llm-agent (commonMain) llm-providers llm-performance (jvmMain + nativeMain) llm-inference/{llama,qwen,gemma,apertus,bert,voxtral} (commonMain + commonTest + jvmTest each) llm-runtime/{kllama,kgemma,kapertus} (commonMain + commonTest + jvmTest each) llm-apps/{skainet-cli,kllama-java-sample,kbert-cli} `:llm-bom` itself is unchanged — line 20 still reads `api(platform("sk.ainet:skainet-bom:${libs.versions.skainet.get()}"))`. - Mirrors the `llm-test/llm-test-java/build.gradle.kts:24` reference pattern that landed in 0.23.4 (`testImplementation(platform(project(":llm-bom")))`), now extended to every module. Verification: - `./gradlew :llm-core:dependencies --configuration jvmRuntimeClasspath` confirms every `sk.ainet.core:skainet-*` coordinate resolves to 0.25.0 via the BOM constraint (e.g. `skainet-lang-core -> 0.25.0`). - `./gradlew assemble` green across all targets including KMP native / wasmJs. - `./gradlew allTests` green (10m 46s). A BOM-coverage regression — e.g. a new SKaiNET artifact missing from the BOM's constraint list — now fails the internal build instead of leaking into a published artifact. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 18 ++++++++---- gradle/libs.versions.toml | 30 +++++++++++++------- llm-agent/build.gradle.kts | 1 + llm-apps/kbert-cli/build.gradle.kts | 2 ++ llm-apps/kllama-java-sample/build.gradle.kts | 2 ++ llm-apps/skainet-cli/build.gradle.kts | 2 ++ llm-core/build.gradle.kts | 6 ++++ llm-inference/apertus/build.gradle.kts | 3 ++ llm-inference/bert/build.gradle.kts | 3 ++ llm-inference/gemma/build.gradle.kts | 3 ++ llm-inference/llama/build.gradle.kts | 3 ++ llm-inference/qwen/build.gradle.kts | 3 ++ llm-inference/voxtral/build.gradle.kts | 3 ++ llm-performance/build.gradle.kts | 2 ++ llm-providers/build.gradle.kts | 2 ++ llm-runtime/kapertus/build.gradle.kts | 3 ++ llm-runtime/kgemma/build.gradle.kts | 3 ++ llm-runtime/kllama/build.gradle.kts | 3 ++ 18 files changed, 75 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 235a8990..14651837 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,18 @@ window without a tagged 0.24.x release on either side. `MongoDB-mdbr-leaf-ir`) so the shell smoke harness and the JVM smoke tier point at the same artifacts. The `smoke-test.sh` script does not yet consume the flag — follow-up. +- **Catalog goes BOM-only.** Every `skainet-*` alias in + `gradle/libs.versions.toml` is now coordinate-only (no `version.ref`); + versions are supplied by the `sk.ainet:skainet-bom` platform + constraint re-exported by `:llm-bom`. Every consumer module gains + `implementation(project.dependencies.platform(project(":llm-bom")))` + in each source set that pulls a `skainet-*` artifact. Bumping the + engine is still a one-line change at the top of the catalog (the + `[versions] skainet = "X.Y.Z"` line drives the BOM platform + reference in `llm-bom/build.gradle.kts`), but every internal build + now exercises the BOM — so a BOM-coverage regression fails locally + instead of leaking into a published artifact. Mirrors the + `llm-test/llm-test-java` reference pattern that landed in 0.23.4. ### Deferred @@ -116,12 +128,6 @@ changes land in follow-up PRs. `Require(BF16)` for GGUF today (no KEEP_NATIVE GGUF backing yet), so this is parked until the engine grows that path. *(SafeTensors BF16 KEEP_NATIVE shipped in this release — see Added.)* -- **BOM-only versionless aliases in `libs.versions.toml`.** Currently - every `skainet-*` alias still uses `version.ref = "skainet"` because - the single-source bump is the lower-risk path during the 0.25.0 - drop. Stripping `version.ref` and adding `platform(project(":llm-bom"))` - to each consumer's `commonMain.dependencies` is a separate - catalog-only PR. - **A `smoke-reference` GitHub Actions job.** The Gradle filter is in place; the CI workflow that triggers it (with self-hosted model cache) lands separately. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c774f238..a9fbdc84 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -78,17 +78,25 @@ kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version. kotest-property = { module = "io.kotest:kotest-property", version.ref = "kotest" } # SKaiNET -skainet-lang-core = { module = "sk.ainet.core:skainet-lang-core", version.ref = "skainet" } -skainet-lang-models = { module = "sk.ainet.core:skainet-lang-models", version.ref = "skainet" } -skainet-lang-ksp-annotations = { module = "sk.ainet.core:skainet-lang-ksp-annotations", version.ref = "skainet" } -skainet-compile-core = { module = "sk.ainet.core:skainet-compile-core", version.ref = "skainet" } -skainet-compile-dag = { module = "sk.ainet.core:skainet-compile-dag", version.ref = "skainet" } -skainet-compile-opt = { module = "sk.ainet.core:skainet-compile-opt", version.ref = "skainet" } -skainet-backend-cpu = { module = "sk.ainet.core:skainet-backend-cpu", version.ref = "skainet" } -skainet-backend-nativeCpu = { module = "sk.ainet.core:skainet-backend-native-cpu", version.ref = "skainet" } -skainet-io-core = { module = "sk.ainet.core:skainet-io-core", version.ref = "skainet" } -skainet-io-gguf = { module = "sk.ainet.core:skainet-io-gguf", version.ref = "skainet" } -skainet-io-safetensors = { module = "sk.ainet.core:skainet-io-safetensors", version.ref = "skainet" } +# +# Coordinate-only — no `version.ref`. Versions are dictated by the +# `sk.ainet:skainet-bom` platform constraint re-exported by `:llm-bom`, +# which downstream consumers and every internal module pull in via +# `implementation(platform(project(":llm-bom")))`. The single +# `skainet = "X.Y.Z"` version above is the source-of-truth for the +# BOM platform itself (`llm-bom/build.gradle.kts:20`), so a bump is +# still a one-line change at the top of this file. +skainet-lang-core = { module = "sk.ainet.core:skainet-lang-core" } +skainet-lang-models = { module = "sk.ainet.core:skainet-lang-models" } +skainet-lang-ksp-annotations = { module = "sk.ainet.core:skainet-lang-ksp-annotations" } +skainet-compile-core = { module = "sk.ainet.core:skainet-compile-core" } +skainet-compile-dag = { module = "sk.ainet.core:skainet-compile-dag" } +skainet-compile-opt = { module = "sk.ainet.core:skainet-compile-opt" } +skainet-backend-cpu = { module = "sk.ainet.core:skainet-backend-cpu" } +skainet-backend-nativeCpu = { module = "sk.ainet.core:skainet-backend-native-cpu" } +skainet-io-core = { module = "sk.ainet.core:skainet-io-core" } +skainet-io-gguf = { module = "sk.ainet.core:skainet-io-gguf" } +skainet-io-safetensors = { module = "sk.ainet.core:skainet-io-safetensors" } [plugins] androidLibrary = { id = "com.android.library", version.ref = "agp" } diff --git a/llm-agent/build.gradle.kts b/llm-agent/build.gradle.kts index 1a2fc44a..438ed1ec 100644 --- a/llm-agent/build.gradle.kts +++ b/llm-agent/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.skainet.lang.core) implementation(project(":llm-core")) implementation(libs.kotlinx.serialization.json) diff --git a/llm-apps/kbert-cli/build.gradle.kts b/llm-apps/kbert-cli/build.gradle.kts index 0a59dc43..e083ce09 100644 --- a/llm-apps/kbert-cli/build.gradle.kts +++ b/llm-apps/kbert-cli/build.gradle.kts @@ -9,6 +9,8 @@ application { } dependencies { + implementation(platform(project(":llm-bom"))) + implementation(project(":llm-inference:bert")) implementation(libs.skainet.lang.core) implementation(libs.skainet.io.core) diff --git a/llm-apps/kllama-java-sample/build.gradle.kts b/llm-apps/kllama-java-sample/build.gradle.kts index e08e8209..9b307a64 100644 --- a/llm-apps/kllama-java-sample/build.gradle.kts +++ b/llm-apps/kllama-java-sample/build.gradle.kts @@ -19,6 +19,8 @@ application { sourceSets["main"].java.srcDir("src/main/java") dependencies { + implementation(platform(project(":llm-bom"))) + implementation(project(":llm-runtime:kllama")) implementation(project(":llm-agent")) implementation(project(":llm-inference:llama")) diff --git a/llm-apps/skainet-cli/build.gradle.kts b/llm-apps/skainet-cli/build.gradle.kts index 948558da..c2279954 100644 --- a/llm-apps/skainet-cli/build.gradle.kts +++ b/llm-apps/skainet-cli/build.gradle.kts @@ -11,6 +11,8 @@ application { } dependencies { + implementation(platform(project(":llm-bom"))) + // Core implementation(project(":llm-core")) implementation(project(":llm-agent")) diff --git a/llm-core/build.gradle.kts b/llm-core/build.gradle.kts index f3f8ade7..e77b2191 100644 --- a/llm-core/build.gradle.kts +++ b/llm-core/build.gradle.kts @@ -43,6 +43,11 @@ kotlin { sourceSets { commonMain.dependencies { + // BOM-only: every skainet-* alias is versionless; this platform + // constraint (re-exporting sk.ainet:skainet-bom) supplies the + // versions. Bumping the engine is then a one-line change at the + // top of `gradle/libs.versions.toml`. + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.skainet.lang.core) implementation(libs.skainet.compile.dag) implementation(libs.skainet.compile.opt) @@ -60,6 +65,7 @@ kotlin { val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.junit) implementation(libs.skainet.io.gguf) diff --git a/llm-inference/apertus/build.gradle.kts b/llm-inference/apertus/build.gradle.kts index 0f491d7e..0e6d74c9 100644 --- a/llm-inference/apertus/build.gradle.kts +++ b/llm-inference/apertus/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.skainet.lang.core) implementation(libs.skainet.io.core) implementation(libs.skainet.io.gguf) @@ -54,12 +55,14 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.backend.cpu) } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.junit) implementation(libs.kotlinx.coroutines.test) diff --git a/llm-inference/bert/build.gradle.kts b/llm-inference/bert/build.gradle.kts index 4909e2f9..e5095eac 100644 --- a/llm-inference/bert/build.gradle.kts +++ b/llm-inference/bert/build.gradle.kts @@ -41,6 +41,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) api(project(":llm-core")) implementation(libs.skainet.lang.core) implementation(libs.skainet.io.safetensors) @@ -51,11 +52,13 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.kotlinx.coroutines.test) implementation(libs.skainet.backend.cpu) diff --git a/llm-inference/gemma/build.gradle.kts b/llm-inference/gemma/build.gradle.kts index efdd5e64..38be270d 100644 --- a/llm-inference/gemma/build.gradle.kts +++ b/llm-inference/gemma/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.skainet.lang.core) implementation(libs.skainet.io.core) implementation(libs.skainet.io.gguf) @@ -54,12 +55,14 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.backend.cpu) } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.junit) implementation(libs.kotlinx.coroutines.test) diff --git a/llm-inference/llama/build.gradle.kts b/llm-inference/llama/build.gradle.kts index e4fae322..ac2df268 100644 --- a/llm-inference/llama/build.gradle.kts +++ b/llm-inference/llama/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.skainet.lang.core) implementation(libs.skainet.io.core) implementation(libs.skainet.io.gguf) @@ -54,12 +55,14 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.backend.cpu) } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.junit) implementation(libs.kotlinx.coroutines.test) diff --git a/llm-inference/qwen/build.gradle.kts b/llm-inference/qwen/build.gradle.kts index e8299501..59723949 100644 --- a/llm-inference/qwen/build.gradle.kts +++ b/llm-inference/qwen/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) api(project(":llm-inference:llama")) implementation(project(":llm-core")) implementation(libs.skainet.lang.core) @@ -55,12 +56,14 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.backend.cpu) } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.junit) implementation(libs.kotlinx.coroutines.test) diff --git a/llm-inference/voxtral/build.gradle.kts b/llm-inference/voxtral/build.gradle.kts index 82a1ab45..b3bf564b 100644 --- a/llm-inference/voxtral/build.gradle.kts +++ b/llm-inference/voxtral/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) api(project(":llm-inference:llama")) implementation(project(":llm-core")) implementation(libs.skainet.lang.core) @@ -55,12 +56,14 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.backend.cpu) } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.junit) implementation(libs.kotlinx.coroutines.test) diff --git a/llm-performance/build.gradle.kts b/llm-performance/build.gradle.kts index 4336cad3..9d71080b 100644 --- a/llm-performance/build.gradle.kts +++ b/llm-performance/build.gradle.kts @@ -57,6 +57,7 @@ kotlin { val jvmMain by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(project(":llm-core")) implementation(project(":llm-inference:llama")) implementation(project(":llm-runtime:kllama")) @@ -83,6 +84,7 @@ kotlin { val nativeMain by creating { dependsOn(commonMain.get()) dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(project(":llm-core")) implementation(project(":llm-inference:llama")) implementation(project(":llm-runtime:kllama")) diff --git a/llm-providers/build.gradle.kts b/llm-providers/build.gradle.kts index 40a10884..b5713d96 100644 --- a/llm-providers/build.gradle.kts +++ b/llm-providers/build.gradle.kts @@ -18,6 +18,8 @@ kotlin { } dependencies { + implementation(platform(project(":llm-bom"))) + api(project(":llm-api")) api(project(":llm-core")) api(project(":llm-agent")) diff --git a/llm-runtime/kapertus/build.gradle.kts b/llm-runtime/kapertus/build.gradle.kts index 06e503a2..ce079ad8 100644 --- a/llm-runtime/kapertus/build.gradle.kts +++ b/llm-runtime/kapertus/build.gradle.kts @@ -10,6 +10,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(project(":llm-inference:apertus")) implementation(project(":llm-runtime:kllama")) implementation(project(":llm-core")) @@ -24,12 +25,14 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) } val jvmMain by getting val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.kotlinx.coroutines.test) implementation(libs.skainet.backend.cpu) diff --git a/llm-runtime/kgemma/build.gradle.kts b/llm-runtime/kgemma/build.gradle.kts index 3df8d1a9..922c6bb9 100644 --- a/llm-runtime/kgemma/build.gradle.kts +++ b/llm-runtime/kgemma/build.gradle.kts @@ -69,6 +69,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(project(":llm-inference:gemma")) implementation(project(":llm-core")) implementation(libs.skainet.lang.core) @@ -83,6 +84,7 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.lang.models) implementation(libs.skainet.io.gguf) @@ -104,6 +106,7 @@ kotlin { } val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.kotlinx.coroutines.test) implementation(libs.skainet.backend.cpu) diff --git a/llm-runtime/kllama/build.gradle.kts b/llm-runtime/kllama/build.gradle.kts index e64ad792..120c9a28 100644 --- a/llm-runtime/kllama/build.gradle.kts +++ b/llm-runtime/kllama/build.gradle.kts @@ -61,6 +61,7 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(project(":llm-inference:llama")) implementation(project(":llm-inference:qwen")) implementation(project(":llm-agent")) @@ -79,6 +80,7 @@ kotlin { } commonTest.dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.skainet.lang.models) implementation(libs.skainet.io.gguf) @@ -87,6 +89,7 @@ kotlin { val jvmMain by getting val jvmTest by getting { dependencies { + implementation(project.dependencies.platform(project(":llm-bom"))) implementation(libs.kotlin.test) implementation(libs.kotlinx.coroutines.test) implementation(libs.skainet.backend.cpu)