From 03c3be5e8d9c059dd94bd9a16da689ca3dc9c6a1 Mon Sep 17 00:00:00 2001
From: Claude <noreply@anthropic.com>
Date: Fri, 10 Jul 2026 05:35:21 +0000
Subject: [PATCH 1/2] fix(llama-android): declare publish -> sign task
 dependency (Gradle validation)

The signed snapshot publish failed: Gradle 8's task-output validation rejected
':publishLlamaAndroidOpenclPublicationToCentralSnapshotsRepository' using the *.asc
output of ':signLlamaAndroidPublication' without a declared dependency. Both publications
(llamaAndroid / llamaAndroidOpencl) attach the SAME sourcesJar/javadocJar, so signing
produces shared signature files that the *other* publication's publish task consumes.

Fix (canonical maven-publish + signing multi-publication pattern): make every
AbstractPublishToMaven task depend on every Sign task, so the ordering is explicit.
No-op when signing is off (fork/PR runs without MAVEN_GPG_PRIVATE_KEY have no Sign tasks).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTS5FpMtBLJENTGoRUrp5m
---
 llama-android/build.gradle.kts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/llama-android/build.gradle.kts b/llama-android/build.gradle.kts
index d417ee25..1e1a4b71 100644
--- a/llama-android/build.gradle.kts
+++ b/llama-android/build.gradle.kts
@@ -311,3 +311,13 @@ if (signingKey != null) {
         sign(publishing.publications)
     }
 }
+
+// The two publications (llamaAndroid / llamaAndroidOpencl) share the SAME sourcesJar/javadocJar,
+// so signing produces those shared *.asc files: e.g. the OpenCL publish task reads the CPU
+// publication's Sign output without an inferred dependency, which Gradle 8's task-output
+// validation rejects as an "implicit dependency" (fails: ":publishLlamaAndroidOpencl…" uses the
+// output of ":signLlamaAndroidPublication"). Make every publish task depend on every signing task
+// so the ordering is explicit. No-op when signing is off (tasks.withType<Sign>() is then empty).
+tasks.withType<org.gradle.api.publish.maven.tasks.AbstractPublishToMaven>().configureEach {
+    dependsOn(tasks.withType<org.gradle.plugins.signing.Sign>())
+}

From 69882f31dd7a4f0b9408bb417b466f12465a88e9 Mon Sep 17 00:00:00 2001
From: Claude <noreply@anthropic.com>
Date: Fri, 10 Jul 2026 05:47:10 +0000
Subject: [PATCH 2/2] Upgrade llama.cpp from b9941 to b9947
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The b9941...b9947 range is 12 files (~100 KiB), dominated by Qualcomm
Hexagon DSP + other ggml backend kernel code (upstream-compiled TUs, not
in this project's classifier matrix). The only CPU-side patch-target file
touched is common/arg.cpp, whose sole change is a .set_examples() metadata
edit adding LLAMA_EXAMPLE_CLI to -of/--output-file — a different region
than patch 0001's parse-function block. All eight patches apply unchanged;
no project source changes required.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTS5FpMtBLJENTGoRUrp5m
---
 CLAUDE.md                                  | 8 ++++----
 README.md                                  | 2 +-
 docs/history/llama-cpp-breaking-changes.md | 2 ++
 llama/CMakeLists.txt                       | 4 ++--
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index f372111b..4704fbbd 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
 
 Java bindings for [llama.cpp](https://github.com/ggerganov/llama.cpp) via JNI, providing a high-level API for LLM inference in Java. The Java layer communicates with a native C++ library through JNI.
 
-Current llama.cpp pinned version: **b9941**
+Current llama.cpp pinned version: **b9947**
 
 ## Upgrading CUDA Version
 
@@ -421,7 +421,7 @@ needs no extra step here, `build-webui` re-reads the tag and rebuilds the matchi
 ships no UI):
 ```bash
 # needs node/npm + network; embed.cpp is plain C++17 (no npm)
-git clone --depth 1 --branch b9941 https://github.com/ggml-org/llama.cpp /tmp/lc
+git clone --depth 1 --branch b9947 https://github.com/ggml-org/llama.cpp /tmp/lc
 ( cd /tmp/lc/tools/ui && npm ci && npm run build \
   && ( cd dist && find . -type f -not -path './_gzip/*' \
        | while read -r f; do mkdir -p "_gzip/$(dirname "$f")"; gzip -9 -c "$f" > "_gzip/$f"; done ) \
@@ -461,7 +461,7 @@ cache lives in **Depot Cache** over sccache's **WebDAV** backend:
 - `SCCACHE_WEBDAV_TOKEN: ${{ secrets.DEPOT_TOKEN }}` — a Depot **organization** token, stored
   as the repo secret **`DEPOT_TOKEN`**.
 
-Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b9941`), the
+Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b9947`), the
 ~280 upstream object files are byte-identical every run, so a warm cache recompiles only the
 *changed* files. Depot's cache is **shared across all branches** (unlike GitHub's
 per-branch `actions/cache`), so every branch builds incrementally; a `b<nnnn>` version bump
@@ -1228,7 +1228,7 @@ ctest --test-dir build --output-on-failure -R "ResultsToJson"
 
 #### Upstream source location (in CMake build tree)
 
-llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b9941`.
+llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b9947`.
 
 **GoogleTest** is a separate `BUILD_TESTING`-only FetchContent (`GIT_TAG v1.17.0`), used solely
 by the `jllama_test` C++ unit-test binary — not by the shipped library, and not coupled to the
diff --git a/README.md b/README.md
index 2d2edcc6..768216ce 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 **Build:**  
 ![Java 8+](https://img.shields.io/badge/Java-8%2B-informational)  
 ![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows%20%7C%20Android-lightgrey)  
-[![llama.cpp b9941](https://img.shields.io/badge/llama.cpp-%23b9941-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b9941)  
+[![llama.cpp b9947](https://img.shields.io/badge/llama.cpp-%23b9947-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b9947)  
 [![JPMS](https://img.shields.io/badge/JPMS-modular%20JAR-25A162)](https://openjdk.org/projects/jigsaw/)  
 ![JUnit](https://img.shields.io/badge/tested%20with-JUnit6-25A162)  
 [![JSpecify](https://img.shields.io/badge/JSpecify-1.0.0%20%40NullMarked-25A162)](https://jspecify.dev)  
diff --git a/docs/history/llama-cpp-breaking-changes.md b/docs/history/llama-cpp-breaking-changes.md
index d25bd3fa..c157b6c5 100644
--- a/docs/history/llama-cpp-breaking-changes.md
+++ b/docs/history/llama-cpp-breaking-changes.md
@@ -467,3 +467,5 @@ Used during `llama.cpp` version bumps: when upgrading, scan this file from the r
 | b9938–b9940 | upstream verification (sandbox) | All **eight** patches (`0001`–`0008`) re-verified against b9940: applied in filename order onto a clean b9940 checkout, all clean (the range touches no patch-target file). No OuteTTS generator anchor touched (`tools/tts/tts.cpp` unchanged). Full build + `ctest` to be confirmed by the CI pipeline. |
 | b9940–b9941 | `ggml/src/ggml-cuda/mmvq.cu` | Internal-only, no API surface (1 file, single commit). A CUDA MMVQ (quantized mat-vec) kernel fix — initializes two scalars to `1.0f` and refactors a conditional to use the loop index `i` instead of `threadIdx.x`. GPU backend only, inside an upstream-compiled TU (and not part of the Android AAR). All **eight** priority headers byte-identical across the range; no project source changes required. |
 | b9940–b9941 | upstream verification (compare diff) | All **eight** patches (`0001`–`0008`) apply unchanged against b9941: the single-commit range touches only `ggml/src/ggml-cuda/mmvq.cu` — no patch-target file (`common/arg.*`, `tools/server/*`) and no OuteTTS generator anchor (`tools/tts/tts.cpp` unchanged), confirmed via the upstream `b9940...b9941` compare diff. Full configure (fail-loud patch apply + TTS extraction) + build + `ctest` to be confirmed by the CI pipeline. |
+| b9941–b9947 | `common/arg.cpp` + `ggml/src/ggml-hexagon/**` + ggml backend TUs | **Additive-only, no public-API break** (12 files, ~100 KiB — the bulk is Qualcomm Hexagon DSP backend + other ggml backend kernel code inside upstream-compiled TUs, not in this project's classifier matrix / not in the Android AAR). CPU-side, the only patch-target file touched is `common/arg.cpp`, whose sole change is metadata: the `-of`/`--output-file` argument gains `LLAMA_EXAMPLE_CLI` in its `.set_examples()` list (the new in-process CLI tool — cf. b9924–b9927 — now advertises the flag). This is a different region than patch `0001`'s `common_params_parse`/`common_params_parse_main`/`GetCommandLineW` block, so `0001` still applies. All **eight** priority headers byte-identical across the range; no project source changes required. |
+| b9941–b9947 | upstream verification (compare diff) | All **eight** patches (`0001`–`0008`) apply unchanged against b9947: the `common/arg.cpp` change is a localized `.set_examples()` metadata edit that does not overlap patch `0001`'s parse-function region, no `tools/server/*` file is touched (`0002`–`0008` unaffected), and no OuteTTS generator anchor (`tools/tts/tts.cpp` unchanged) — confirmed via the upstream `b9941...b9947` compare diff. Full configure (fail-loud patch apply + TTS extraction) + build + `ctest` to be confirmed by the CI pipeline. |
diff --git a/llama/CMakeLists.txt b/llama/CMakeLists.txt
index b351fefa..0ae91525 100644
--- a/llama/CMakeLists.txt
+++ b/llama/CMakeLists.txt
@@ -174,7 +174,7 @@ set(LLAMA_BUILD_APP OFF CACHE BOOL "" FORCE)
 FetchContent_Declare(
 	llama.cpp
 	GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git
-	GIT_TAG        b9941
+	GIT_TAG        b9947
 	PATCH_COMMAND  ${CMAKE_COMMAND}
 		-DPATCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}/patches
 		-DLLAMA_SRC=<SOURCE_DIR>
@@ -197,7 +197,7 @@ execute_process(
     COMMAND ${CMAKE_COMMAND}
         -DTTS_SRC=${llama.cpp_SOURCE_DIR}/tools/tts/tts.cpp
         -DOUT_CPP=${JLLAMA_TTS_GEN_CPP}
-        -DLLAMA_TAG=b9941
+        -DLLAMA_TAG=b9947
         -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate-tts-upstream.cmake
     RESULT_VARIABLE JLLAMA_TTS_GEN_RESULT
 )
