build(agent): weasel-1#856f80 iteration

This commit is contained in:
agent-856f80a92b1141b4 2026-04-24 20:20:04 +02:00
parent b71a0d1e4b
commit 04ed82bc21
2 changed files with 32 additions and 0 deletions

View File

@ -3,6 +3,8 @@ from __future__ import annotations
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, List, Optional, Any from typing import Dict, List, Optional, Any
import time import time
import json
import hashlib
@dataclass @dataclass
@ -58,5 +60,30 @@ class GraphOfContractsRegistry:
raise KeyError(f"Contract {contract_id} not found") raise KeyError(f"Contract {contract_id} not found")
rec.attestations.append(attestation) rec.attestations.append(attestation)
def generate_attestation(self, contract_id: str) -> str:
"""Create a deterministic SHA-256 attestation for a registered contract.
The attestation is computed over a canonical JSON serialization of the
contract metadata (name, version, contract_id, schema, signer, timestamp)
to ensure repeatability for audits and replay checks.
"""
rec = self.contracts.get(contract_id)
if rec is None:
raise KeyError(f"Contract {contract_id} not found")
# Canonical JSON serialization for deterministic hashing
payload = {
"name": rec.name,
"version": rec.version,
"contract_id": rec.contract_id,
"schema": rec.schema,
"signer": rec.signer,
"timestamp": rec.timestamp,
}
data = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
h = hashlib.sha256(data).hexdigest()
att = f"sha256:{h}"
rec.attestations.append(att)
return att
__all__ = ["ContractRecord", "GraphOfContractsRegistry"] __all__ = ["ContractRecord", "GraphOfContractsRegistry"]

View File

@ -18,3 +18,8 @@ def test_registry_basic_operations():
assert c.name == "toyAdapter" assert c.name == "toyAdapter"
reg.add_attestation("idea-1", "attestation-123") reg.add_attestation("idea-1", "attestation-123")
assert reg.get_contract("idea-1").attestations[-1] == "attestation-123" assert reg.get_contract("idea-1").attestations[-1] == "attestation-123"
# generate deterministic sha256 attestation and ensure it's appended
att = reg.generate_attestation("idea-1")
assert isinstance(att, str)
assert att.startswith("sha256:")
assert reg.get_contract("idea-1").attestations[-1] == att