From 2f8f971822eee339557297224114ba44ec3b57ee Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Sat, 5 Sep 2026 14:26:25 -0400 Subject: [PATCH] fix(OMN-17871): bind primary artifact metadata evidence --- ...rsd-model-artifact-provenance.example.yaml | 15 ++++++- .../model_rsd_artifact_source_relation.py | 36 ++++++++++++++++ .../model_rsd_model_artifact_provenance.py | 8 +++- .../runtime/rsd_model_artifact_provenance.py | 2 +- .../test_model_serialization_roundtrip.py | 1 + .../test_rsd_model_artifact_provenance.py | 43 ++++++++++++++++++- 6 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 src/omnibase_infra/runtime/models/model_rsd_artifact_source_relation.py diff --git a/docker/lane-overlays/dev.rsd-model-artifact-provenance.example.yaml b/docker/lane-overlays/dev.rsd-model-artifact-provenance.example.yaml index 875534686b..903c371d03 100644 --- a/docker/lane-overlays/dev.rsd-model-artifact-provenance.example.yaml +++ b/docker/lane-overlays/dev.rsd-model-artifact-provenance.example.yaml @@ -1,5 +1,5 @@ # OMN-17871: inert example only; not an activation or deployment record. -schema_version: rsd.model-artifact-provenance.v1 +schema_version: rsd.model-artifact-provenance.v2 execute_enabled: false approval_status: unapproved model_id: qwen/qwen3.8-27b @@ -9,6 +9,17 @@ artifact_id: gittensor-model-hub/Qwen3.8-27B-NVFP4-RTX5090 artifact_revision_sha: 0cc27958cefbbe231782ec8511de8c4eb5233348 artifact_manifest_digest_sha256: e46ef4e3895ed0a6db7c237d642121095629c53bd5b3e5ac799b8a8e2ae83e4f artifact_manifest_algorithm: sha256-path-size-content-sha256-v1 +artifact_source_relation: + # Revision-scoped primary metadata; this does not claim weight derivation. + source_metadata_authority: huggingface-model-revision-api-v1 + source_model_card_sha256: 57e4bdb258ee1a7d2635c5174ebd4e56abe392505cdb5f8bbb356b0dc4293641 + source_config_sha256: 191e0af232104ed8b65258cf3fb2b842e288008baca7633c11b82a1ac7203aab + artifact_metadata_authority: huggingface-model-revision-api-v1 + artifact_model_card_sha256: 3704987ff0e2206ab934af6d71cd0a9b5140536ee8d305aa7ba6e7665f135058 + artifact_embedded_source_model_card_sha256: 57e4bdb258ee1a7d2635c5174ebd4e56abe392505cdb5f8bbb356b0dc4293641 + artifact_declared_base_model_id: Qwen/Qwen3.8-27B + relation_status: publisher-declared-unverified + approval_status: not-approved quantization: modelopt_nvfp4 weight_activation_precision: w4a4 kv_cache_dtype: fp8 @@ -24,6 +35,6 @@ expires_at: "2026-09-04T20:00:00Z" signer_capability_ref: capability://rsd/model-artifact-provenance/signer signer_key_id: 00000000-0000-4000-8000-000000000003 signer_public_key_fingerprint_sha256: "0000000000000000000000000000000000000000000000000000000000000000" -signature_domain: omninode-rsd.model-artifact-provenance.v1 +signature_domain: omninode-rsd.model-artifact-provenance.v2 # Sentinel signature: an operator must issue a real signature before approval. signature_base64: N9Eiaa5K2V9Ay9uS09n8Gh-KmtdsiOjle1bypnfa_CEj1y-zZkvMulCu5ZlHHLSZ364R_qeoX9pejwGHI_ijCw== diff --git a/src/omnibase_infra/runtime/models/model_rsd_artifact_source_relation.py b/src/omnibase_infra/runtime/models/model_rsd_artifact_source_relation.py new file mode 100644 index 0000000000..6c8a5a74f3 --- /dev/null +++ b/src/omnibase_infra/runtime/models/model_rsd_artifact_source_relation.py @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2025 OmniNode.ai Inc. +# SPDX-License-Identifier: MIT +"""Primary metadata evidence for the inert RSD artifact binding.""" + +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel, ConfigDict + + +class ModelRsdArtifactSourceRelation(BaseModel): + """Immutable primary-metadata evidence with an explicit non-approval state.""" + + model_config = ConfigDict(frozen=True, extra="forbid", strict=True) + + source_metadata_authority: Literal["huggingface-model-revision-api-v1"] + source_model_card_sha256: Literal[ + "57e4bdb258ee1a7d2635c5174ebd4e56abe392505cdb5f8bbb356b0dc4293641" + ] + source_config_sha256: Literal[ + "191e0af232104ed8b65258cf3fb2b842e288008baca7633c11b82a1ac7203aab" + ] + artifact_metadata_authority: Literal["huggingface-model-revision-api-v1"] + artifact_model_card_sha256: Literal[ + "3704987ff0e2206ab934af6d71cd0a9b5140536ee8d305aa7ba6e7665f135058" + ] + artifact_embedded_source_model_card_sha256: Literal[ + "57e4bdb258ee1a7d2635c5174ebd4e56abe392505cdb5f8bbb356b0dc4293641" + ] + artifact_declared_base_model_id: Literal["Qwen/Qwen3.8-27B"] + relation_status: Literal["publisher-declared-unverified"] + approval_status: Literal["not-approved"] + + +__all__ = ["ModelRsdArtifactSourceRelation"] diff --git a/src/omnibase_infra/runtime/models/model_rsd_model_artifact_provenance.py b/src/omnibase_infra/runtime/models/model_rsd_model_artifact_provenance.py index 9463f8cc5a..8a70a0972f 100644 --- a/src/omnibase_infra/runtime/models/model_rsd_model_artifact_provenance.py +++ b/src/omnibase_infra/runtime/models/model_rsd_model_artifact_provenance.py @@ -8,6 +8,9 @@ from pydantic import BaseModel, ConfigDict, Field +from omnibase_infra.runtime.models.model_rsd_artifact_source_relation import ( + ModelRsdArtifactSourceRelation, +) from omnibase_infra.runtime.models.rsd_live_delegation_schema import ( _RFC3339_UTC, CanonicalCapabilityRef, @@ -22,7 +25,7 @@ class ModelRsdModelArtifactProvenance(BaseModel): model_config = ConfigDict(frozen=True, extra="forbid", strict=True) - schema_version: Literal["rsd.model-artifact-provenance.v1"] + schema_version: Literal["rsd.model-artifact-provenance.v2"] execute_enabled: Literal[False] approval_status: Literal["unapproved"] model_id: Literal["qwen/qwen3.8-27b"] @@ -34,6 +37,7 @@ class ModelRsdModelArtifactProvenance(BaseModel): "e46ef4e3895ed0a6db7c237d642121095629c53bd5b3e5ac799b8a8e2ae83e4f" ] artifact_manifest_algorithm: Literal["sha256-path-size-content-sha256-v1"] + artifact_source_relation: ModelRsdArtifactSourceRelation quantization: Literal["modelopt_nvfp4"] weight_activation_precision: Literal["w4a4"] kv_cache_dtype: Literal["fp8"] @@ -51,7 +55,7 @@ class ModelRsdModelArtifactProvenance(BaseModel): signer_capability_ref: CanonicalCapabilityRef signer_key_id: CanonicalUuid4 signer_public_key_fingerprint_sha256: CanonicalSha256 - signature_domain: Literal["omninode-rsd.model-artifact-provenance.v1"] + signature_domain: Literal["omninode-rsd.model-artifact-provenance.v2"] signature_base64: CanonicalEd25519Signature diff --git a/src/omnibase_infra/runtime/rsd_model_artifact_provenance.py b/src/omnibase_infra/runtime/rsd_model_artifact_provenance.py index 8d1e096a0a..04c31d0c7f 100644 --- a/src/omnibase_infra/runtime/rsd_model_artifact_provenance.py +++ b/src/omnibase_infra/runtime/rsd_model_artifact_provenance.py @@ -25,7 +25,7 @@ ModelRsdModelArtifactProvenance, ) -_AUTHORITY_DOMAIN = b"omninode-rsd.model-artifact-provenance.v1\x00" +_AUTHORITY_DOMAIN = b"omninode-rsd.model-artifact-provenance.v2\x00" _MAX_PROVENANCE_BYTES = 64 * 1024 _MAX_NESTING_DEPTH = 32 _MAX_VALIDITY_WINDOW_SECONDS = 300 diff --git a/tests/unit/models/test_model_serialization_roundtrip.py b/tests/unit/models/test_model_serialization_roundtrip.py index 70f3f39420..66d4934be3 100644 --- a/tests/unit/models/test_model_serialization_roundtrip.py +++ b/tests/unit/models/test_model_serialization_roundtrip.py @@ -232,6 +232,7 @@ # and fail-closed plugin fixture, not the generic round-trip factory set. "ModelRsdPostgresAcceptanceOverlay": "Typed operator overlay covered by test_rsd_postgres_acceptance_overlay.py", "ModelRsdModelArtifactProvenance": "Strict loader, canonical signing-preimage, and signature coverage in test_rsd_model_artifact_provenance.py", + "ModelRsdArtifactSourceRelation": "Strict primary-metadata and non-approval coverage in test_rsd_model_artifact_provenance.py", # OMN-17861: canonical JSON strict roundtrips for all five public models # live beside the signed fixture and pure-preflight hostile coverage. "ModelRsdLiveDelegationOverlay": "Explicit canonical roundtrip coverage in test_rsd_live_delegation_overlay.py", diff --git a/tests/unit/runtime/test_rsd_model_artifact_provenance.py b/tests/unit/runtime/test_rsd_model_artifact_provenance.py index db898f9f7f..1ee4c38e2e 100644 --- a/tests/unit/runtime/test_rsd_model_artifact_provenance.py +++ b/tests/unit/runtime/test_rsd_model_artifact_provenance.py @@ -93,6 +93,23 @@ def test_example_is_inert_and_binds_immutable_public_identity() -> None: assert provenance.artifact_manifest_algorithm == ( "sha256-path-size-content-sha256-v1" ) + assert provenance.artifact_source_relation.source_metadata_authority == ( + "huggingface-model-revision-api-v1" + ) + assert provenance.artifact_source_relation.source_model_card_sha256 == ( + "57e4bdb258ee1a7d2635c5174ebd4e56abe392505cdb5f8bbb356b0dc4293641" + ) + assert provenance.artifact_source_relation.artifact_model_card_sha256 == ( + "3704987ff0e2206ab934af6d71cd0a9b5140536ee8d305aa7ba6e7665f135058" + ) + assert ( + provenance.artifact_source_relation.artifact_embedded_source_model_card_sha256 + == provenance.artifact_source_relation.source_model_card_sha256 + ) + assert provenance.artifact_source_relation.relation_status == ( + "publisher-declared-unverified" + ) + assert provenance.artifact_source_relation.approval_status == "not-approved" assert provenance.quantization == "modelopt_nvfp4" assert provenance.weight_activation_precision == "w4a4" assert provenance.kv_cache_dtype == "fp8" @@ -208,6 +225,7 @@ def test_freshness_rejects_excess_window_and_non_utc_clock() -> None: ("artifact_revision_sha", "0" * 40), ("artifact_manifest_digest_sha256", "0" * 64), ("artifact_manifest_algorithm", "sha256-canonical-json-v1"), + ("artifact_source_relation", {}), ("runtime_version", "0.27.0"), ("served_model_id", "Qwen/qwen3.8-27b"), ("launch_profile_id", "qwen38-nvfp4-rtx4090-v1"), @@ -236,6 +254,7 @@ def test_exact_candidate_bindings_reject_substitution( "artifact_revision_sha", "artifact_manifest_digest_sha256", "artifact_manifest_algorithm", + "artifact_source_relation", "runtime_version", "served_model_id", "launch_profile_id", @@ -260,6 +279,28 @@ def test_schema_is_strict_and_execute_can_never_be_enabled() -> None: ModelRsdModelArtifactProvenance.model_validate(raw, strict=True) +@pytest.mark.unit +@pytest.mark.parametrize( + ("field", "value"), + [ + ("relation_status", "verified"), + ("approval_status", "approved"), + ("artifact_declared_base_model_id", "Qwen/Qwen3.8-14B"), + ("source_model_card_sha256", "0" * 64), + ], +) +def test_primary_metadata_relation_cannot_assert_unverified_derivation( + field: str, value: str +) -> None: + raw = _raw_example() + relation = raw["artifact_source_relation"] + assert type(relation) is dict + relation[field] = value + + with pytest.raises(ValidationError): + ModelRsdModelArtifactProvenance.model_validate(raw, strict=True) + + @pytest.mark.unit @pytest.mark.parametrize( ("field", "value"), @@ -406,5 +447,5 @@ def test_preimage_is_canonical_json() -> None: provenance, _ = _signed_example() preimage = provenance_signing_preimage(provenance) - assert preimage.startswith(b"omninode-rsd.model-artifact-provenance.v1\x00{") + assert preimage.startswith(b"omninode-rsd.model-artifact-provenance.v2\x00{") assert json.dumps(json.loads(preimage.split(b"\x00", 1)[1]), separators=(",", ":"))