feat: implement numbered patch-stack apply/verify enforcement (DGR-028)

Split the range-loader patch into single-concern patches 0002-0005 (loader,
filtered state report, boundary I/O endpoint guard, worker range-report
hook), add UPSTREAM-ASSUMPTIONS.json describing each patch's assumptions,
and enforce control-plane/license boundary checks plus first-incompatible-
patch reporting in scripts/llama_cpp_dependency.py apply/reverse/verify.

7 passed in tests/test_llama_cpp_dependency.py; SHA256SUMS verified against
all five patches; focused native CTest (test-meshnet-range-ownership 1/1)
recorded in evidence README (build/ dir not present in this environment to
independently reverify).
This commit is contained in:
Dobromir Popov
2026-07-21 13:22:55 +03:00
parent 902ecde363
commit 7da90ef475
14 changed files with 1027 additions and 186 deletions

View File

@@ -0,0 +1,202 @@
From: Meshnet <meshnet@invalid>
Subject: [PATCH] llama: expose worker-owned range report hook and fixture
Concern: worker hooks. Exposes the llama_model_meshnet_range_report C API the
project-owned worker binds to and registers a model-free native fixture that
loads tiny generated GGUF ranges and asserts ownership, endpoint, and
byte-report invariants.
---
diff --git a/include/llama.h b/include/llama.h
index 8a7521349..5818daf94 100644
--- a/include/llama.h
+++ b/include/llama.h
@@ -613,6 +613,13 @@ extern "C" {
// Get metadata value as a string by key name
LLAMA_API int32_t llama_model_meta_val_str(const struct llama_model * model, const char * key, char * buf, size_t buf_size);
+ // Returns false unless this model was instantiated through the Meshnet
+ // owned-range loader. Values are derived from registered tensors and
+ // backend buffers, never copied from caller-supplied parameters.
+ LLAMA_API bool llama_model_meshnet_range_report(
+ const struct llama_model * model,
+ struct llama_meshnet_range_report * out);
+
// Get the number of metadata key/value pairs
LLAMA_API int32_t llama_model_meta_count(const struct llama_model * model);
diff --git a/src/llama-model.cpp b/src/llama-model.cpp
index 2ea8598ad..c9d3cf6d3 100644
--- a/src/llama-model.cpp
+++ b/src/llama-model.cpp
@@ -2695,6 +2695,10 @@ uint64_t llama_model_size(const llama_model * model) {
return model->size();
}
+bool llama_model_meshnet_range_report(const llama_model * model, llama_meshnet_range_report * out) {
+ return model != nullptr && model->meshnet_range_report(out);
+}
+
const char * llama_model_chat_template(const llama_model * model, const char * name) {
const auto key = name ? LLM_KV(model->arch, name)(LLM_KV_TOKENIZER_CHAT_TEMPLATE)
: LLM_KV(model->arch)(LLM_KV_TOKENIZER_CHAT_TEMPLATE);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 855295c15..9a7be6eed 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -193,6 +193,7 @@ if (NOT WIN32 OR NOT BUILD_SHARED_LIBS)
# llama_build_and_test(test-double-float.cpp) # SLOW
llama_build_and_test(test-llama-archs.cpp)
+ llama_build_and_test(test-meshnet-range-ownership.cpp)
endif()
llama_build_and_test(test-chat-peg-parser.cpp peg-parser/simple-tokenize.cpp)
diff --git a/tests/test-meshnet-range-ownership.cpp b/tests/test-meshnet-range-ownership.cpp
new file mode 100644
index 000000000..6b3aa5ac5 100644
--- /dev/null
+++ b/tests/test-meshnet-range-ownership.cpp
@@ -0,0 +1,143 @@
+#include "ggml.h"
+#include "gguf.h"
+#include "llama.h"
+
+#include "../src/llama-model.h"
+
+#include <cstdio>
+#include <cstring>
+#include <stdexcept>
+#include <string>
+
+namespace {
+
+constexpr int kLayers = 4;
+constexpr int kEmbd = 8;
+constexpr int kFfn = 16;
+constexpr int kVocab = 16;
+
+void check(bool condition, const char * message) {
+ if (!condition) {
+ throw std::runtime_error(message);
+ }
+}
+
+void add_tensor(gguf_context * gguf, ggml_context * tensors, const char * name, int d0, int d1 = 1) {
+ ggml_tensor * tensor = d1 == 1
+ ? ggml_new_tensor_1d(tensors, GGML_TYPE_F32, d0)
+ : ggml_new_tensor_2d(tensors, GGML_TYPE_F32, d0, d1);
+ ggml_set_name(tensor, name);
+ std::memset(tensor->data, 0, ggml_nbytes(tensor));
+ gguf_add_tensor(gguf, tensor);
+}
+
+std::string write_fixture() {
+ const std::string path = "meshnet-dense-llama-range-fixture.gguf";
+ gguf_context * gguf = gguf_init_empty();
+ ggml_init_params params = { 128 * 1024, nullptr, false };
+ ggml_context * tensors = ggml_init(params);
+ check(gguf && tensors, "failed to create dense-Llama fixture contexts");
+
+ gguf_set_val_str(gguf, "general.architecture", "llama");
+ gguf_set_val_u32(gguf, "llama.context_length", 16);
+ gguf_set_val_u32(gguf, "llama.embedding_length", kEmbd);
+ gguf_set_val_u32(gguf, "llama.block_count", kLayers);
+ gguf_set_val_u32(gguf, "llama.feed_forward_length", kFfn);
+ gguf_set_val_u32(gguf, "llama.attention.head_count", 2);
+ gguf_set_val_u32(gguf, "llama.attention.head_count_kv", 2);
+ gguf_set_val_u32(gguf, "llama.rope.dimension_count", 4);
+ gguf_set_val_f32(gguf, "llama.attention.layer_norm_rms_epsilon", 1.0e-5f);
+ gguf_set_val_str(gguf, "tokenizer.ggml.model", "no_vocab");
+ gguf_set_val_u32(gguf, "llama.vocab_size", kVocab);
+
+ add_tensor(gguf, tensors, "token_embd.weight", kEmbd, kVocab);
+ add_tensor(gguf, tensors, "output_norm.weight", kEmbd);
+ add_tensor(gguf, tensors, "output.weight", kEmbd, kVocab);
+ for (int layer = 0; layer < kLayers; ++layer) {
+ const std::string p = "blk." + std::to_string(layer) + ".";
+ add_tensor(gguf, tensors, (p + "attn_norm.weight").c_str(), kEmbd);
+ add_tensor(gguf, tensors, (p + "attn_q.weight").c_str(), kEmbd, kEmbd);
+ add_tensor(gguf, tensors, (p + "attn_k.weight").c_str(), kEmbd, kEmbd);
+ add_tensor(gguf, tensors, (p + "attn_v.weight").c_str(), kEmbd, kEmbd);
+ add_tensor(gguf, tensors, (p + "attn_output.weight").c_str(), kEmbd, kEmbd);
+ add_tensor(gguf, tensors, (p + "ffn_norm.weight").c_str(), kEmbd);
+ add_tensor(gguf, tensors, (p + "ffn_gate.weight").c_str(), kEmbd, kFfn);
+ add_tensor(gguf, tensors, (p + "ffn_down.weight").c_str(), kFfn, kEmbd);
+ add_tensor(gguf, tensors, (p + "ffn_up.weight").c_str(), kEmbd, kFfn);
+ }
+ check(gguf_write_to_file(gguf, path.c_str(), false), "failed to write dense-Llama fixture");
+ ggml_free(tensors);
+ gguf_free(gguf);
+ return path;
+}
+
+int block_number(const std::string & name) {
+ int block = -1;
+ return std::sscanf(name.c_str(), "blk.%d.", &block) == 1 ? block : -1;
+}
+
+bool is_allowed_endpoint_tensor(const std::string & name, int start, int end) {
+ if (name == "token_embd.weight") {
+ return start == 0;
+ }
+ if (name == "output_norm.weight" || name == "output.weight") {
+ return end == kLayers;
+ }
+ return false;
+}
+
+llama_meshnet_range_report load_and_check(const std::string & path, int start, int end) {
+ llama_model_params params = llama_model_default_params();
+ params.meshnet_owned_layer_start = start;
+ params.meshnet_owned_layer_end = end;
+ llama_model * model = llama_model_load_from_file(path.c_str(), params);
+ check(model != nullptr, "failed to load dense-Llama fixture");
+
+ llama_meshnet_range_report report = {};
+ check(llama_model_meshnet_range_report(model, &report), "range report is absent");
+ check(report.start_layer == start, "reported start does not match registered range");
+ check(report.end_layer == end, "reported end does not match registered range");
+ check(report.mapped_bytes > 0, "mmap report is empty");
+ check(report.resident_bytes >= report.mapped_bytes, "resident bytes undercount mapped bytes");
+ check(report.has_token_embeddings == (start == 0), "token-embedding ownership is not the head endpoint");
+ check(report.has_output_head == (end == kLayers), "output-head ownership is not the tail endpoint");
+
+ const auto & tensors = llama_internal_get_tensor_map(model);
+ check(!tensors.empty(), "no tensors registered for owned range");
+ for (const auto & [name, _] : tensors) {
+ const int block = block_number(name);
+ check((block >= start && block < end) || (block == -1 && is_allowed_endpoint_tensor(name, start, end)),
+ "registered tensor is outside the owned range and its endpoints");
+ }
+ llama_model_free(model);
+ return report;
+}
+
+} // namespace
+
+int main() {
+ llama_backend_init();
+ const std::string fixture = write_fixture();
+
+ const auto head = load_and_check(fixture, 0, 1);
+ const auto middle = load_and_check(fixture, 1, 3);
+ load_and_check(fixture, 3, 4);
+ check(middle.mapped_bytes > head.mapped_bytes, "two-layer range did not map more bytes than head");
+
+ // A stock load has no owned-range report and registers every tensor.
+ llama_model * stock = llama_model_load_from_file(fixture.c_str(), llama_model_default_params());
+ check(stock != nullptr, "stock load failed");
+ llama_meshnet_range_report stock_report = {};
+ check(!llama_model_meshnet_range_report(stock, &stock_report), "stock load reported an owned range");
+ check(llama_internal_get_tensor_map(stock).size() == 3 + 9 * kLayers, "stock load lost tensors");
+ llama_model_free(stock);
+
+ llama_model_params invalid = llama_model_default_params();
+ invalid.meshnet_owned_layer_start = 3;
+ invalid.meshnet_owned_layer_end = 5;
+ check(llama_model_load_from_file(fixture.c_str(), invalid) == nullptr, "invalid range loaded");
+
+ std::remove(fixture.c_str());
+ llama_backend_free();
+ return 0;
+}