From 5ebddec772adeb0e546682c024aebc2a8ecf244d Mon Sep 17 00:00:00 2001 From: Bernard Ladenthin Date: Sun, 25 Oct 2026 22:38:06 +0100 Subject: [PATCH] Remove the push of the pinned llama.cpp commit to the fork mirror-llama-source pushed every release's pinned upstream commit to bernardladenthin/llama.cpp as jllama/b and needed a write token for the fork (LLAMA_MIRROR_TOKEN) that was never provisioned. The owner maintains that fork, so the job, its script and its tests go. Builds always fetched from upstream and still do; the signed source archive of a release stays and is what rebuilds a release without upstream. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VszvDmRRPP1UcwozsUMY1L --- .github/buildcheck/tests/test_mirror.py | 163 ------------------------ .github/mirror-llama-source.sh | 80 ------------ .github/release-gate-exemptions.txt | 1 - .github/workflows/publish.yml | 52 +------- CHANGELOG.md | 7 +- CLAUDE.md | 16 +-- TODO.md | 17 +-- llama/CMakeLists.txt | 13 +- 8 files changed, 13 insertions(+), 336 deletions(-) delete mode 100644 .github/buildcheck/tests/test_mirror.py delete mode 100755 .github/mirror-llama-source.sh diff --git a/.github/buildcheck/tests/test_mirror.py b/.github/buildcheck/tests/test_mirror.py deleted file mode 100644 index 0f5ed223..00000000 --- a/.github/buildcheck/tests/test_mirror.py +++ /dev/null @@ -1,163 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Bernard Ladenthin -# -# SPDX-License-Identifier: MIT OR Apache-2.0 - -import base64 -import json -import os -import shutil -import subprocess -import tempfile -import unittest -from pathlib import Path - -from actionlib.common import workflow -from buildcheck.tests.helpers import REPO - - -GIT = shutil.which("git") -BASH = shutil.which("bash") -TOKEN = "mirror-dummy-token-for-tests" -URL = "https://github.com/owner/mirror.git" - - -@unittest.skipUnless(GIT and BASH, "git and bash are required") -class MirrorTest(unittest.TestCase): - def setUp(self): - self.temp = tempfile.TemporaryDirectory() - self.addCleanup(self.temp.cleanup) - self.root = Path(self.temp.name) - self.source = self.root / "source" - self.source.mkdir() - self.log = self.root / "calls.jsonl" - self.env = {**os.environ, "GIT_CONFIG_NOSYSTEM": "1", "GIT_CONFIG_GLOBAL": "/dev/null", - "GIT_CONFIG_COUNT": "0", "GIT_TERMINAL_PROMPT": "0", "GITHUB_ACTIONS": "false", - "LLAMA_MIRROR_TOKEN": TOKEN} - self.git("init", "-q", "--object-format=sha1") - self.git("-c", "user.name=Test", "-c", "user.email=test@example.invalid", - "-c", "commit.gpgsign=false", "commit", "--allow-empty", "-qm", "fixture") - self.sha = self.git("rev-parse", "HEAD").strip() - (self.root / "llama").mkdir() - (self.root / "llama/CMakeLists.txt").write_text( - f'set(JLLAMA_GIT_TAG b1)\nset(JLLAMA_GIT_COMMIT "{self.sha}")\n') - scripts = self.root / ".github" - scripts.mkdir() - self.script = scripts / "mirror-llama-source.sh" - shutil.copyfile(Path(REPO) / ".github/mirror-llama-source.sh", self.script) - - # Like checkout v7: credentials in an included file, with a URL-specific header. - credentials = self.root / "checkout-credentials.config" - subprocess.run([GIT, "config", "--file", str(credentials), - "http.https://github.com/.extraheader", "AUTHORIZATION: basic CHECKOUT_DUMMY"], - check=True, env=self.env) - self.git("config", "include.path", str(credentials)) - # A stale exact-URL setting must also be replaced, not appended as a second auth header. - self.git("config", f"http.{URL}.extraheader", "AUTHORIZATION: basic STALE_DUMMY") - self.git("config", f"credential.{URL}.helper", "unused-dummy-helper") - self.config_before = (self.source / ".git/config").read_bytes() - self.credentials_before = credentials.read_bytes() - - # Real Git handles every local operation and the config lookup. Network operations are - # intercepted before Git can run them, so this suite cannot contact or write to GitHub. - fake = self.root / "bin/git" - fake.parent.mkdir() - fake.write_text('''#!/usr/bin/env python3 -import json, os, subprocess, sys -args = sys.argv[1:] -operation = next((value for value in ("ls-remote", "push") if value in args), None) -if operation is None: - raise SystemExit(subprocess.call([os.environ["REAL_GIT"], *args])) -prefix = args[:args.index(operation)] -url = next(value for value in args if value.startswith("https://")) -def config(key): - result = subprocess.run([os.environ["REAL_GIT"], *prefix, "config", "--get-urlmatch", key, url], - text=True, capture_output=True) - return [line for line in result.stdout.splitlines() if line] -with open(os.environ["MIRROR_TEST_LOG"], "a") as log: - log.write(json.dumps({"operation": operation, "args": args, - "headers": config("http.extraheader"), - "helpers": config("credential.helper"), - "prompt": os.environ.get("GIT_TERMINAL_PROMPT")}) + "\\n") -if os.environ.get("MIRROR_TEST_FAIL") == operation: - print("simulated authentication/transport failure", file=sys.stderr) - raise SystemExit(128) -if operation == "ls-remote" and os.environ.get("MIRROR_TEST_EXISTING"): - print(os.environ["MIRROR_TEST_EXISTING"] + "\\trefs/tags/jllama/b1") -''') - fake.chmod(0o755) - self.env.update({"REAL_GIT": GIT, "MIRROR_TEST_LOG": str(self.log), - "PATH": str(fake.parent) + os.pathsep + os.environ["PATH"]}) - - def git(self, *args): - result = subprocess.run([GIT, "-C", str(self.source), *args], env=self.env, - capture_output=True, text=True, check=True) - return result.stdout - - def run_script(self, **environment): - return subprocess.run([BASH, str(self.script), str(self.source), "owner/mirror"], - env={**self.env, **environment}, capture_output=True, text=True) - - def calls(self): - return [json.loads(line) for line in self.log.read_text().splitlines()] if self.log.exists() else [] - - def test_explicit_mirror_token_replaces_inherited_credentials_without_persisting_or_argv_secret(self): - result = self.run_script() - self.assertEqual(result.returncode, 0, result.stdout + result.stderr) - calls = self.calls() - self.assertEqual([call["operation"] for call in calls], ["ls-remote", "push"]) - encoded = base64.b64encode(("x-access-token:" + TOKEN).encode()).decode() - for call in calls: - self.assertEqual(call["headers"], ["AUTHORIZATION: basic " + encoded]) - self.assertEqual(call["helpers"], []) - self.assertEqual(call["prompt"], "0") - self.assertNotIn(TOKEN, " ".join(call["args"])) - self.assertNotIn(encoded, " ".join(call["args"])) - self.assertNotIn(TOKEN, result.stdout + result.stderr) - self.assertNotIn(encoded, result.stdout + result.stderr) - self.assertEqual((self.source / ".git/config").read_bytes(), self.config_before) - self.assertEqual((self.root / "checkout-credentials.config").read_bytes(), self.credentials_before) - self.assertEqual(calls[-1]["args"][-1], self.sha + ":refs/tags/jllama/b1") - self.assertNotIn("--force", calls[-1]["args"]) - - def test_existing_matching_tag_needs_no_push(self): - result = self.run_script(MIRROR_TEST_EXISTING=self.sha) - self.assertEqual(result.returncode, 0, result.stdout + result.stderr) - self.assertEqual([call["operation"] for call in self.calls()], ["ls-remote"]) - - def test_existing_different_tag_is_never_overwritten(self): - result = self.run_script(MIRROR_TEST_EXISTING="a" * 40) - self.assertNotEqual(result.returncode, 0) - self.assertIn("one number, one commit", result.stderr) - self.assertEqual([call["operation"] for call in self.calls()], ["ls-remote"]) - - def test_failed_remote_read_is_not_treated_as_an_absent_tag(self): - result = self.run_script(MIRROR_TEST_FAIL="ls-remote") - self.assertNotEqual(result.returncode, 0) - self.assertEqual([call["operation"] for call in self.calls()], ["ls-remote"]) - - def test_failed_push_remains_a_failure(self): - result = self.run_script(MIRROR_TEST_FAIL="push") - self.assertNotEqual(result.returncode, 0) - self.assertNotIn("mirror-llama-source: pushed", result.stdout) - - def test_missing_token_and_wrong_source_are_refused_before_any_network_call(self): - result = self.run_script(LLAMA_MIRROR_TOKEN="") - self.assertNotEqual(result.returncode, 0) - self.assertIn("LLAMA_MIRROR_TOKEN is empty", result.stderr) - (self.root / "llama/CMakeLists.txt").write_text( - 'set(JLLAMA_GIT_TAG b1)\nset(JLLAMA_GIT_COMMIT "' + "a" * 40 + '")\n') - result = self.run_script() - self.assertNotEqual(result.returncode, 0) - self.assertEqual(self.calls(), []) - - def test_both_mirror_checkouts_disable_persisted_credentials(self): - jobs = workflow.parse((Path(REPO) / ".github/workflows/publish.yml").read_text()) - checkouts = [step for step in jobs["mirror-llama-source"].steps() - if any("uses: actions/checkout@" in line for line in step)] - self.assertEqual(len(checkouts), 2) - for step in checkouts: - self.assertIn(" persist-credentials: false", step) - - -if __name__ == "__main__": - unittest.main() diff --git a/.github/mirror-llama-source.sh b/.github/mirror-llama-source.sh deleted file mode 100755 index e4572f36..00000000 --- a/.github/mirror-llama-source.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash - -# SPDX-FileCopyrightText: 2026 Bernard Ladenthin -# -# SPDX-License-Identifier: MIT OR Apache-2.0 - -# Pushes the pinned llama.cpp commit to the project's mirror (bernardladenthin/llama.cpp, a fork -# of ggml-org/llama.cpp) as the tag `jllama/b`, so the commit a release was built from stays -# fetchable when upstream's tag or repository goes away: `-DJLLAMA_GIT_REPOSITORY=` in -# llama/CMakeLists.txt then serves the same commit (TODO.md, delivery roadmap, item 6). The patches -# stay files in this repository; the mirror holds pristine upstream commits only, so the review -# surface remains the patch file. -# -# Idempotent: a tag that already names this commit is left alone; a tag that names ANOTHER commit -# fails loudly -- a number maps to exactly one commit (upstream's own rule), so that is a defect, -# never something to overwrite. -# -# Usage: LLAMA_MIRROR_TOKEN= .github/mirror-llama-source.sh [] -# a full git clone at the pinned commit (fetch-depth 0: the push needs the -# commit's history, which the mirror shares with upstream anyway) -# owner/name, default bernardladenthin/llama.cpp -# LLAMA_MIRROR_TOKEN a token with contents:write on the mirror (an environment secret of the -# release job); the script fails without it rather than skipping -# Exit codes: 0 mirrored (or already there), 1 a check failed. - -set -euo pipefail - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -SRC="${1:?usage: mirror-llama-source.sh []}" -MIRROR="${2:-bernardladenthin/llama.cpp}" -CMAKELISTS="$ROOT/llama/CMakeLists.txt" - -fail() { - echo "::error::mirror-llama-source: $*" >&2 - exit 1 -} - -[ -n "${LLAMA_MIRROR_TOKEN:-}" ] || fail "LLAMA_MIRROR_TOKEN is empty -- the release job needs that secret to push to $MIRROR" -[[ "$MIRROR" =~ ^[A-Za-z0-9-]+/[A-Za-z0-9_.-]+$ ]] \ - && [ "${MIRROR##*/}" != "." ] && [ "${MIRROR##*/}" != ".." ] \ - || fail "mirror must be a GitHub owner/repository name" -[ -d "$SRC/.git" ] || fail "$SRC is not a git checkout" - -TAG=$(grep -oE '^set\(JLLAMA_GIT_TAG[[:space:]]+b[0-9]+\)' "$CMAKELISTS" | grep -oE 'b[0-9]+' | head -1) -[ -n "$TAG" ] || fail "could not resolve JLLAMA_GIT_TAG (b) from $CMAKELISTS" -COMMIT=$(grep -oE '^set\(JLLAMA_GIT_COMMIT[[:space:]]+"[0-9a-f]{40}"\)' "$CMAKELISTS" | grep -oE '[0-9a-f]{40}' | head -1 || true) -HEAD_COMMIT=$(git -C "$SRC" rev-parse HEAD) -if [ -n "$COMMIT" ] && [ "$HEAD_COMMIT" != "$COMMIT" ]; then - fail "$SRC is at $HEAD_COMMIT, but JLLAMA_GIT_COMMIT pins $COMMIT" -fi -[ -f "$SRC/.git/shallow" ] && fail "$SRC is a shallow clone; the push needs the full history (fetch-depth 0)" -COUNT=$(git -C "$SRC" rev-list --count HEAD) -[ "$COUNT" = "${TAG#b}" ] || fail "the checked-out commit $HEAD_COMMIT is b$COUNT, not $TAG" - -MIRROR_URL="https://github.com/$MIRROR.git" -REF="refs/tags/jllama/$TAG" -# Match only this mirror URL, replacing any inherited checkout header for it. Pass the header -# through the environment, not argv or a persistent Git config. Requires Git >= 2.31. -JLLAMA_MIRROR_AUTH_HEADER="AUTHORIZATION: basic $(printf '%s' "x-access-token:$LLAMA_MIRROR_TOKEN" | base64 -w0)" -export JLLAMA_MIRROR_AUTH_HEADER -if [ "${GITHUB_ACTIONS:-}" = "true" ]; then - echo "::add-mask::${JLLAMA_MIRROR_AUTH_HEADER#AUTHORIZATION: basic }" -fi -mirror_git() { - GIT_TERMINAL_PROMPT=0 git -C "$SRC" \ - -c "credential.$MIRROR_URL.helper=" \ - -c "http.$MIRROR_URL.extraheader=" \ - --config-env="http.$MIRROR_URL.extraheader=JLLAMA_MIRROR_AUTH_HEADER" "$@" -} - -EXISTING=$(mirror_git ls-remote --tags "$MIRROR_URL" "$REF" | cut -f1) -if [ -n "$EXISTING" ]; then - if [ "$EXISTING" = "$HEAD_COMMIT" ]; then - echo "mirror-llama-source: $MIRROR already has $REF = $HEAD_COMMIT; nothing to push" - exit 0 - fi - fail "$MIRROR has $REF = $EXISTING, but $TAG is $HEAD_COMMIT here -- one number, one commit; resolve by hand" -fi -mirror_git push "$MIRROR_URL" "$HEAD_COMMIT:$REF" -echo "mirror-llama-source: pushed $HEAD_COMMIT to $MIRROR as $REF" diff --git a/.github/release-gate-exemptions.txt b/.github/release-gate-exemptions.txt index e20d9086..704cc15e 100644 --- a/.github/release-gate-exemptions.txt +++ b/.github/release-gate-exemptions.txt @@ -18,7 +18,6 @@ verify-signing-key-gradle: same as verify-signing-key, for the Gradle/BouncyCast test-java-llama-langchain4j-integration: validation only; a cold model cache degrades it to self-skips (CLAUDE.md, LangChain4j integration) build-android-llmservice: an app, not a library release; a Compose/AGP pin must not block a release (CLAUDE.md, Android app "LLM Service") test-android-llmservice: the emulator UI test of that app, optional for the same reason -mirror-llama-source: runs after publish-release; pushes the pinned llama.cpp commit to the mirror fork central-snapshot: Independent post-preflight Central transfer; must not gate the GitHub publication path. central-release: Independent post-preflight Central transfer; must not gate the GitHub publication path. attest-snapshot: Independent provenance after the secured handoff; cannot gate either publication consumer. diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 12a6d703..7ff6613e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -772,9 +772,7 @@ jobs: # upstream (no fetch, no patching: the archived tree carries the applier's stamp, which # verify-patches-applied.sh checks against the patches on disk). The publish jobs sign the # archive with the release key and attach it next to the Maven artifacts, so "no release asset - # is attached that CI has not run" holds for it too. mirror-llama-source (after a release) pushes - # the pristine commit to bernardladenthin/llama.cpp as jllama/b, the fallback the - # configure's JLLAMA_GIT_REPOSITORY can be pointed at. + # is attached that CI has not run" holds for it too. # --------------------------------------------------------------------------- archive-llama-source: name: Archive the patched llama.cpp source @@ -3777,54 +3775,6 @@ jobs: assets-complete: ${{ needs.publish-release.outputs.assets_complete }} github-token: ${{ secrets.GITHUB_TOKEN }} - mirror-llama-source: - name: Mirror the pinned llama.cpp commit to bernardladenthin/llama.cpp - needs: [publish-release] - if: ${{ !cancelled() && needs.publish-release.result == 'success' }} - runs-on: ubuntu-latest - # The pristine upstream commit every natives jar of this release was built from, pushed to the - # project's fork as the tag jllama/b (.github/mirror-llama-source.sh: idempotent, and a - # tag that names another commit fails rather than being moved). Together with the signed source - # archive this is what keeps a release rebuildable without upstream (TODO.md, delivery roadmap, - # item 6); the configure takes the mirror through -DJLLAMA_GIT_REPOSITORY. LLAMA_MIRROR_TOKEN - # is a token with contents:write on the fork, kept with the release secrets; the job fails - # without it rather than skipping, so a release never silently goes unmirrored. - environment: maven-central - permissions: - contents: read - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - persist-credentials: false - - name: Resolve pinned llama.cpp tag from CMakeLists.txt - id: tag - shell: bash - run: | - # The same rule as build-webui: JLLAMA_GIT_TAG is the number, JLLAMA_GIT_COMMIT the commit - # it names; the checkout takes the commit when it is set. - TAG=$(grep -oE '^set\(JLLAMA_GIT_TAG[[:space:]]+b[0-9]+\)' llama/CMakeLists.txt | grep -oE 'b[0-9]+' | head -1) - if [ -z "$TAG" ]; then - echo "could not resolve llama.cpp JLLAMA_GIT_TAG (b) from CMakeLists.txt" >&2 - exit 1 - fi - COMMIT=$(grep -oE '^set\(JLLAMA_GIT_COMMIT[[:space:]]+"[0-9a-f]{40}"\)' llama/CMakeLists.txt | grep -oE '[0-9a-f]{40}' | head -1 || true) - echo "tag=$TAG" >> "$GITHUB_OUTPUT" - echo "ref=${COMMIT:-$TAG}" >> "$GITHUB_OUTPUT" - echo "Pinned llama.cpp: $TAG${COMMIT:+ (commit $COMMIT)}" - - name: Checkout llama.cpp at the pinned commit (full history, the push needs it) - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - with: - persist-credentials: false - repository: ggml-org/llama.cpp - ref: ${{ steps.tag.outputs.ref }} - path: llama-src - fetch-depth: 0 - - name: Push the commit as jllama/ to the mirror - shell: bash - env: - LLAMA_MIRROR_TOKEN: ${{ secrets.LLAMA_MIRROR_TOKEN }} - run: bash .github/mirror-llama-source.sh llama-src bernardladenthin/llama.cpp - central-snapshot: name: Upload checked snapshot artifacts to Maven Central needs: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b2021a2..eb044def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -242,14 +242,11 @@ the first two items break every existing consumer at upgrade. jars into a directory and starts from it with no natives jar on the classpath. README, "Natives outside Maven", documents the directory, how to fetch a natives jar without Maven and the WDAC / AppLocker case. -- **The patched llama.cpp source of a release is an asset of its own, and mirrored.** +- **The patched llama.cpp source of a release is an asset of its own.** `archive-llama-source` packs the pinned commit with the patches applied, reproducibly, as `llama.cpp-b-jllama--src.tar.gz`, signed and attached with the Maven artifacts; `test-source-archive` builds the C++ suite from that archive before either publish job runs, and a - consumer rebuilds a release with `-DFETCHCONTENT_SOURCE_DIR_LLAMA.CPP=`. After a release - `mirror-llama-source` pushes the pinned commit to `bernardladenthin/llama.cpp` as `jllama/b` - (`JLLAMA_GIT_REPOSITORY` selects the mirror for a build); the patches stay files in this - repository, never fork commits. + consumer rebuilds a release with `-DFETCHCONTENT_SOURCE_DIR_LLAMA.CPP=`. - **Modular natives: the GPU backends are additive module jars, and every platform a GPU can join is built modular.** A GPU natives jar (`cuda13-linux-x86-64`, `vulkan-windows-aarch64`, ... -- 15 of them) now holds **only** ggml's backend module for that GPU (`libggml-cuda.so`, `ggml-vulkan.dll`, diff --git a/CLAUDE.md b/CLAUDE.md index 079d770d..68cc7436 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1538,7 +1538,7 @@ exist yet: `git show` returned an empty file, the grep found nothing, and "upstr was read out of a file that was never read. **A drop-check that cannot distinguish "no match" from "nothing examined" has not been run.** -## Source archive and mirror: a release stays rebuildable without upstream +## Source archive: a release stays rebuildable without upstream Every natives jar is compiled from the pinned upstream commit plus `llama/patches/`, a tree that used to exist only transiently in each build job's `_deps/`. Two jobs of `publish.yml` keep it @@ -1569,20 +1569,6 @@ used to exist only transiently in each build job's `_deps/`. Two jobs of `publis artifacts: a GitHub-only file of the signed publication, so the gate verifies its signature and `attest-*` covers it (see "Signed publication"). A consumer rebuilds a release with `cmake -B build -DFETCHCONTENT_SOURCE_DIR_LLAMA.CPP=`. -- **`mirror-llama-source`** (after a successful `publish-release`, exempt from the release gate like - the attach jobs; `.github/mirror-llama-source.sh`): pushes the pristine pinned commit to the fork - `bernardladenthin/llama.cpp` as the tag `jllama/b` -- idempotent, and a tag that already - names another commit fails rather than being moved. It needs `LLAMA_MIRROR_TOKEN` (contents:write - on the fork) in the `maven-central` environment and **fails without it** rather than skipping. The - configure's `JLLAMA_GIT_REPOSITORY` cache variable (default upstream) is where the mirror is - selected. The patches stay files in this repository, never fork commits: the review surface is the - patch file. - - Both mirror-job checkouts set `persist-credentials: false`. The script passes the mirror token - through Git's `--config-env`, scoped to the exact mirror URL, and clears inherited headers/helpers - for that URL; a failed remote lookup fails the job. Tests in `test_mirror.py` use dummy credentials - with real Git configuration resolution and intercepted network calls. Cross-repo policy: - [`../workspace/policies/git-checkout-credentials.md`](../workspace/policies/git-checkout-credentials.md). ## The C API: `jllama_api.h` over the engine (layer B) diff --git a/TODO.md b/TODO.md index 9b37091c..831c75ae 100644 --- a/TODO.md +++ b/TODO.md @@ -57,7 +57,6 @@ so entries below describe remaining work or an explicit deferral policy. example; keep the existing "Upgrading from 5.1" list current for any further breaking change. - [ ] Set the CHANGELOG release heading/date and footer links, and update `SECURITY.md`'s supported line from `5.x` to `6.x` as part of that release commit. -- [ ] Verify the mirror credential and destination access described in roadmap item 6 below. - [ ] **Owner: the open points of the natives license texts** (`llama/legal/natives/`, in every natives jar since 2026-10-25): whether the oneMKL SYCL headers compiled into the two SYCL modules need Intel's Simplified Software License text (it ships only in Intel's installer); the @@ -84,8 +83,10 @@ The remaining items retain the numbering of the 2026-10-15 roadmap referenced by Done and therefore deleted here, while comments in the code still name them by number: **1** the provenance record (`jllama-build.txt` keys, `jllama-sbom.json`, `docs/patches.md`; CLAUDE.md, "Modular natives"), **2** the natives directory as a tested contract (`lib.path`; CLAUDE.md, "Native -Library Resolution"), **4** export hygiene (the export lists; CLAUDE.md, "Natives jars"), **7** layer -B, the `jllama_*` C API (CLAUDE.md, "The C API"; `docs/c-api.md`), **9** the decision for 6.0.0 +Library Resolution"), **4** export hygiene (the export lists; CLAUDE.md, "Natives jars"), **6** the +signed source archive of a release (CLAUDE.md, "Source archive"; the push of the pinned commit to a +fork was removed again on 2026-10-25, the owner maintains that fork), **7** layer B, the `jllama_*` +C API (CLAUDE.md, "The C API"; `docs/c-api.md`), **9** the decision for 6.0.0 (section "Release 6.0.0" above) and **10** `llama-ffm` (CLAUDE.md, "Java 22+ without JNI"). Windows code signing stays deferred by the owner's decision. Vendor hash pinning and the measurements below remain open hardening/coverage work; they do not establish a runtime defect. @@ -114,16 +115,6 @@ measurements below remain open hardening/coverage work; they do not establish a `c_abi`. The existing plain-C compile/smoke runs without a model; Java/C++/FFM inference coverage does not exercise this particular consumer. macOS and s390x remain static builds. -### 6. Release mirror — destination credential and first real push - -- [ ] **Owner:** verify/provision `LLAMA_MIRROR_TOKEN` with contents-write access to - `bernardladenthin/llama.cpp` in the `maven-central` environment before the release. - Its current availability cannot be inferred from a snapshot run: `mirror-llama-source` - is release-only and was skipped in run 39922567350. The credential-selection fix is on - this branch; tests with temporary repositories do not prove real destination access. -- [ ] Check the first actual `mirror-llama-source` release run and the immutable upstream tag - it creates. Source-archive creation and `test-source-archive` are already CI-covered. - ### 8. Cached/uncached reproducibility measurement (C.3) - [ ] Compare native hashes from cached and uncached builds of the same commit before considering diff --git a/llama/CMakeLists.txt b/llama/CMakeLists.txt index 30c34ff7..c2778f3d 100644 --- a/llama/CMakeLists.txt +++ b/llama/CMakeLists.txt @@ -384,15 +384,12 @@ else() message(STATUS "llama.cpp ${JLLAMA_GIT_TAG} is fetched by tag name (JLLAMA_GIT_COMMIT is empty; CI would refuse this)") endif() -# Where the pinned commit is fetched from. The default is upstream; the mirror -# bernardladenthin/llama.cpp (every pinned commit is pushed there as the tag jllama/b by the -# mirror-llama-source job of publish.yml) serves the same commit when upstream's repository or tag -# is gone -- the commit hash is identical in both, so nothing else changes. The archived patched -# source of every release (llama.cpp-b-jllama--src.tar.gz on the GitHub release) is -# the third way: -DFETCHCONTENT_SOURCE_DIR_LLAMA.CPP=. TODO.md, delivery roadmap, -# item 6. +# Where the pinned commit is fetched from: upstream. Any other clone that carries the same commit +# serves as well -- the commit hash is the pin, so nothing else changes. Without any repository, the +# archived patched source of a release (llama.cpp-b-jllama--src.tar.gz on the GitHub +# release) builds it: -DFETCHCONTENT_SOURCE_DIR_LLAMA.CPP=. set(JLLAMA_GIT_REPOSITORY "https://github.com/ggerganov/llama.cpp.git" CACHE STRING - "The git repository llama.cpp is fetched from (upstream, or the mirror https://github.com/bernardladenthin/llama.cpp.git)") + "The git repository llama.cpp is fetched from (upstream, or any clone carrying the pinned commit)") FetchContent_Declare( llama.cpp GIT_REPOSITORY ${JLLAMA_GIT_REPOSITORY}