diff --git a/gridverse/registry.py b/gridverse/registry.py index 205fc87..3c6e50d 100644 --- a/gridverse/registry.py +++ b/gridverse/registry.py @@ -30,10 +30,29 @@ class GraphContractRegistry: self._adapters[(adapter_type, version)] = payload def conformance_test(self, adapter_iface: Dict[str, Any], contract_schema: Dict[str, Any]) -> bool: + """Check adapter-contract conformance. + + This test is intentionally lenient to support both legacy payloads and + payload-with-metadata structures. Some code paths register contracts as + plain payload dicts (legacy) while newer paths store contracts under a + {"payload": ..., "metadata": ...} wrapper. Accept either form for + compatibility while ensuring the adapter is present as well. + """ key = (adapter_iface.get("name"), adapter_iface.get("version")) contract_key = (contract_schema.get("name"), contract_schema.get("version")) adapters_ok = getattr(self, "_adapters", {}).get(key) is not None - contracts_ok = self._contracts.get(contract_key) is not None + entry = self._contracts.get(contract_key) + # Accept both legacy payload form and new wrapped form + contracts_ok = False + if isinstance(entry, dict): + # New style with payload/metadata + if "payload" in entry: + contracts_ok = True + else: + # treat dict-like legacy payload as present + contracts_ok = True if entry else False + else: + contracts_ok = entry is not None return adapters_ok and contracts_ok # Extended API: support metadata-aware contract registration without breaking @@ -51,6 +70,10 @@ class GraphContractRegistry: if isinstance(entry, dict) and "payload" in entry: return entry # Fallback to legacy payload storage if present + # Support both: a raw payload dict, or None + if isinstance(entry, dict): + # Legacy form where the entry itself is the payload dict + return {"payload": entry, "metadata": {}} return {"payload": entry, "metadata": {}}