271 lines
8.1 KiB
Python
271 lines
8.1 KiB
Python
"""Deterministic DGR-003 identity and tracker-admission conformance tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import replace
|
|
import json
|
|
from pathlib import Path
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from meshnet_node.runtime_recipe import (
|
|
ArtifactIdentity,
|
|
CompatibilityFingerprint,
|
|
DerivativeBinding,
|
|
RecipeIdentityError,
|
|
RuntimeRecipe,
|
|
ShardIdentity,
|
|
check_handshake,
|
|
check_route,
|
|
handshake_error,
|
|
)
|
|
from meshnet_tracker.capability import (
|
|
STATE_ADMITTED,
|
|
STATE_FINGERPRINT_MISMATCH,
|
|
STATE_MODEL_MISMATCH,
|
|
STATE_RECIPE_MISMATCH,
|
|
STATE_UNCERTIFIED,
|
|
evaluate_report,
|
|
)
|
|
from meshnet_tracker.server import TrackerServer, _capability_from_registration
|
|
from meshnet_tracker.recipe import (
|
|
CertificationLedger,
|
|
DistributedForwardEvidence,
|
|
parse_identity,
|
|
)
|
|
|
|
|
|
def _digest(char: str) -> str:
|
|
return char * 64
|
|
|
|
|
|
def _identity(start: int = 0, end: int = 4, **recipe_changes: object) -> ShardIdentity:
|
|
recipe_fields: dict[str, object] = {
|
|
"weight_quantization": "Q4_K_M",
|
|
"activation_dtype": "bfloat16",
|
|
"compute_dtype": "float32",
|
|
"kv_dtype": "q8_0",
|
|
"kv_layout": "paged-v1",
|
|
"tokenizer_revision": "0123456789abcdef",
|
|
"architecture_adapter": "llama/range-v1",
|
|
"backend_id": "llama.cpp",
|
|
"runtime_version": "llama.cpp@deadbeef+meshnet.1",
|
|
"recipe_id": "example-gguf",
|
|
"recipe_version": "1",
|
|
"catalogue_version": "2026.07.1",
|
|
}
|
|
recipe_fields.update(recipe_changes)
|
|
recipe = RuntimeRecipe(**recipe_fields) # type: ignore[arg-type]
|
|
return ShardIdentity(
|
|
ArtifactIdentity(
|
|
"example/model",
|
|
"0123456789abcdef",
|
|
_digest("a"),
|
|
"dense-llama",
|
|
_digest("b"),
|
|
8,
|
|
),
|
|
recipe,
|
|
start,
|
|
end,
|
|
)
|
|
|
|
|
|
def _report(identity: ShardIdentity) -> dict:
|
|
return {
|
|
"schema_version": 1,
|
|
"model": {"model_id": "example/model"},
|
|
"shard": {"start": identity.shard_start, "end": identity.shard_end - 1},
|
|
"recipe": identity.recipe.to_dict() | {
|
|
"recipe_id": identity.recipe.recipe_id,
|
|
"recipe_version": identity.recipe.recipe_version,
|
|
"catalogue_version": identity.recipe.catalogue_version,
|
|
},
|
|
"backend": {"backend_id": "llama.cpp", "device": "test"},
|
|
"status": "passed",
|
|
"validated_at": 100.0,
|
|
"duration_ms": 1,
|
|
"diagnostics": [],
|
|
"identity": identity.to_dict(),
|
|
}
|
|
|
|
|
|
def _evaluate(report: dict, **kwargs: object):
|
|
return evaluate_report(
|
|
report,
|
|
model_matches=lambda model: model == "example/model",
|
|
advertised_model="example/model",
|
|
shard_start=0,
|
|
shard_end=3,
|
|
now=100.0,
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
def test_node_and_tracker_share_the_committed_canonical_fingerprint_vector():
|
|
vector_path = Path(__file__).parent / "data" / "recipe_fingerprint_vectors.json"
|
|
vector = json.loads(vector_path.read_text(encoding="utf-8"))["vectors"][0]
|
|
expected = vector["fingerprint"]
|
|
identity = ShardIdentity.from_dict(vector["identity"])
|
|
|
|
assert identity.fingerprint.to_dict() == expected
|
|
assert parse_identity(vector["identity"]).fingerprint_dict() == expected
|
|
assert (
|
|
CompatibilityFingerprint.from_proto(identity.fingerprint.to_proto()).to_dict()
|
|
== expected
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"axis,value",
|
|
[
|
|
("weight_quantization", "Q5_K_M"),
|
|
("activation_dtype", "float16"),
|
|
("compute_dtype", "float16"),
|
|
("kv_dtype", "float16"),
|
|
("kv_layout", "contiguous-v2"),
|
|
("tokenizer_revision", "fedcba9876543210"),
|
|
("architecture_adapter", "llama/range-v2"),
|
|
("backend_id", "other-backend"),
|
|
("runtime_version", "llama.cpp@other+meshnet.1"),
|
|
("boundary_schema_version", 2),
|
|
("protocol_schema_version", 2),
|
|
],
|
|
)
|
|
def test_every_recipe_axis_changes_the_fingerprint_and_blocks_route(axis, value):
|
|
left = _identity()
|
|
right = _identity(4, 8, **{axis: value})
|
|
|
|
assert left.fingerprint.key != right.fingerprint.key
|
|
assert check_route([left, right])
|
|
|
|
|
|
def test_split_artifact_is_bound_to_exact_source_and_owned_range():
|
|
source = _identity()
|
|
split = ShardIdentity(
|
|
ArtifactIdentity(
|
|
"example/model",
|
|
"0123456789abcdef",
|
|
_digest("c"),
|
|
"dense-llama",
|
|
_digest("b"),
|
|
8,
|
|
DerivativeBinding(_digest("a"), 4, 8),
|
|
),
|
|
source.recipe,
|
|
4,
|
|
8,
|
|
)
|
|
assert source.fingerprint.matches(split.fingerprint)
|
|
with pytest.raises(RecipeIdentityError):
|
|
ShardIdentity(split.artifact, split.recipe, 3, 8)
|
|
|
|
|
|
def test_declared_digest_mismatch_is_recomputed_and_rejected_not_authenticated():
|
|
report = _report(_identity())
|
|
report["identity"]["fingerprint"]["runtime_recipe_digest"] = _digest("f")
|
|
|
|
assert _evaluate(report).state == STATE_FINGERPRINT_MISMATCH
|
|
|
|
|
|
def test_exact_recipe_registers_dark_until_tracker_certification():
|
|
identity = _identity()
|
|
report = _report(identity)
|
|
ledger = CertificationLedger()
|
|
|
|
dark = _evaluate(report, ledger=ledger)
|
|
assert dark.state == STATE_UNCERTIFIED
|
|
# Unit fixtures cannot promote a recipe: this is the explicit trust boundary.
|
|
with pytest.raises(ValueError, match="synthetic"):
|
|
ledger.certify(
|
|
parse_identity(identity.to_dict()),
|
|
DistributedForwardEvidence(
|
|
"session",
|
|
1,
|
|
("a", "b"),
|
|
((0, 4), (4, 8)),
|
|
1,
|
|
8,
|
|
identity.fingerprint.key,
|
|
synthetic=True,
|
|
),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="fingerprint does not match"):
|
|
ledger.certify(
|
|
parse_identity(identity.to_dict()),
|
|
DistributedForwardEvidence(
|
|
"session",
|
|
1,
|
|
("a", "b"),
|
|
((0, 4), (4, 8)),
|
|
1,
|
|
8,
|
|
(_digest("e"), _digest("f")),
|
|
),
|
|
)
|
|
|
|
|
|
def test_capability_identity_must_match_the_proof_labels():
|
|
identity = _identity()
|
|
|
|
wrong_model = _report(identity)
|
|
wrong_model["identity"]["artifact"]["artifact_id"] = "other/model"
|
|
wrong_model["identity"]["fingerprint"] = None
|
|
assert _evaluate(wrong_model).state == STATE_MODEL_MISMATCH
|
|
|
|
wrong_recipe = _report(identity)
|
|
wrong_recipe["recipe"]["recipe_id"] = "other-recipe"
|
|
assert _evaluate(wrong_recipe).state == STATE_RECIPE_MISMATCH
|
|
|
|
wrong_backend = _report(identity)
|
|
wrong_backend["backend"]["backend_id"] = "other-backend"
|
|
assert _evaluate(wrong_backend).state == STATE_RECIPE_MISMATCH
|
|
|
|
wrong_quantization = _report(identity)
|
|
wrong_quantization["backend"]["quantization"] = "Q5_K_M"
|
|
assert _evaluate(wrong_quantization).state == STATE_RECIPE_MISMATCH
|
|
|
|
|
|
def test_tracker_server_owns_the_ledger_used_by_registration():
|
|
identity = _identity()
|
|
report = _report(identity)
|
|
report["validated_at"] = time.time()
|
|
payload = {"capability_report": report}
|
|
tracker = TrackerServer()
|
|
|
|
def evaluate():
|
|
return _capability_from_registration(
|
|
payload,
|
|
model="example/model",
|
|
hf_repo=None,
|
|
shard_start=0,
|
|
shard_end=3,
|
|
recipe_certifications=tracker._recipe_certifications,
|
|
)
|
|
|
|
assert evaluate().state == STATE_UNCERTIFIED
|
|
tracker._recipe_certifications.certify(
|
|
parse_identity(identity.to_dict()),
|
|
DistributedForwardEvidence(
|
|
"session",
|
|
1,
|
|
("physical-a", "physical-b"),
|
|
((0, 4), (4, 8)),
|
|
1,
|
|
8,
|
|
identity.fingerprint.key,
|
|
),
|
|
)
|
|
assert evaluate().state == STATE_ADMITTED
|
|
|
|
|
|
def test_grpc_handshake_uses_the_dgr_002_fingerprint_and_fails_closed():
|
|
local = _identity()
|
|
remote = replace(local.fingerprint, runtime_recipe_digest=_digest("f")).to_proto()
|
|
|
|
mismatches = check_handshake(local, remote)
|
|
assert mismatches
|
|
assert handshake_error(mismatches).code != 0
|