Index: flexoentity/domain.py
===================================================================
--- flexoentity/domain.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ flexoentity/domain.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -1,5 +1,5 @@
-from uuid import UUID
 from dataclasses import dataclass
-from flexoentity import FlexOID, FlexoEntity, EntityType
+from flexoentity import FlexoEntity, EntityType
+
 
 @dataclass
@@ -26,4 +26,9 @@
         return self.domain_id
 
+    def _deserialize_content(self, content: dict):
+        self.fullname = content.get("fullname", "")
+        self.description = content.get("description", "")
+        self.classification = content.get("classification", "UNCLASSIFIED")
+
     def _serialize_content(self):
         return {
@@ -32,30 +37,10 @@
             "classification": self.classification,
         }
-    
+
     @classmethod
     def from_dict(cls, data):
-        # Must have flexo_id
-        if "flexo_id" not in data:
-            raise ValueError("Domain serialization missing 'flexo_id'.")
 
-        flexo_id = FlexOID(data["flexo_id"])
-
-        obj = cls(
-            fullname=data.get("fullname", ""),
-            description=data.get("description", ""),
-            classification=data.get("classification", "UNCLASSIFIED"),
-            flexo_id=flexo_id,
-            _in_factory=True
-        )
-
-        # Restore metadata
-        obj.origin = data.get("origin")
-        obj.fingerprint = data.get("fingerprint", "")
-        obj.originator_id = (
-            UUID(data["originator_id"]) if data.get("originator_id") else None
-        )
-        obj.owner_id = (
-            UUID(data["owner_id"]) if data.get("owner_id") else None
-        )
-
+        obj = super().from_dict(data)
+        content = data.get("content", {})
+        obj._deserialize_content(content)
         return obj
Index: flexoentity/flexo_entity.py
===================================================================
--- flexoentity/flexo_entity.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ flexoentity/flexo_entity.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -60,6 +60,6 @@
 
 
-from flexoentity.id_factory import FlexOID
-from flexoentity import canonical_seed
+from flexoentity.id_factory import FlexOID, canonical_seed
+from flexoentity.logger import logger
 
 
@@ -170,4 +170,14 @@
         return copy
 
+    @staticmethod
+    def canonicalize_content_dict(data) -> str:
+        """
+        Canonicalize structured content for fingerprinting.
+        - Stable JSON representation
+        - Sorted keys
+        - No whitespace noise
+        """
+        return json.dumps(data, sort_keys=True, separators=(",", ":"))
+
     @property
     @abstractmethod
@@ -190,11 +200,4 @@
         """I return the entity type derived from my FlexOID"""
         return EntityType(self.flexo_id.entity_type)
-
-    def canonical_seed(self) -> str:
-        """
-        I use a helper method to flatten my text_seed.
-        NOTE:This might become superfluous when text_seed provides this by itself. Redesign possible
-        """
-        return canonical_seed(self.text_seed)
 
     @classmethod
@@ -241,5 +244,5 @@
         if not self.subtype:
             self.subtype = self.__class__.__name__
-            
+
     def __str__(self):
         return (
@@ -258,8 +261,4 @@
     }
 
-    @abstractmethod
-    def _serialize_content(self):
-        return {}
-
     def to_dict(self):
         return {
@@ -276,27 +275,33 @@
         - ALWAYS restores the canonical Domain via DomainManager.
         """
-        if "flexo_id" not in data["meta"]:
-            raise ValueError("Serialized entity must include 'flexo_id'.")
-
-        flexo_id = FlexOID(data["meta"]["flexo_id"])
-        subtype = data["subtype"]
-        # canonical domain object
+        meta = data.get("meta", "")
+        # if not meta or meta.get("flexo_id", ""):
+        #    raise ValueError("Serialized entity must include 'flexo_id'.")
+        flexo_id = FlexOID(meta.get("flexo_id"))
+        subtype = meta.get("subtype")
+        if not subtype:
+            raise ValueError("Serialized entity must include 'subtype'.")
+
+        try:
+            owner_id = UUID(meta.get("owner_id"))
+        except ValueError as e:
+            logger.warn(f"Missing or wrong owner_id {e}")
+            owner_id = UUID(int=0)
+        try:
+            originator_id = UUID(meta.get("originator_id"))
+        except ValueError as e:
+            logger.warn(f"Missing or wrong originator_id {e}")
+            originator_id = UUID(int=0)
 
         obj = cls(
             flexo_id=flexo_id,
             subtype=subtype,
+            origin=meta.get("origin", ""),
+            fingerprint=meta.get("fingerprint", ""),
+            owner_id=owner_id,
+            originator_id=originator_id,
             _in_factory=True
         )
-
-        # restore provenance
-        obj.fingerprint = data.get("fingerprint", "")
-        obj.origin = data.get("origin")
-
-        if data.get("originator_id"):
-            obj.originator_id = UUID(data["originator_id"])
-
-        if data.get("owner_id"):
-            obj.owner_id = UUID(data["owner_id"])
-
+        obj._deserialize_content(data)
         return obj
 
@@ -311,41 +316,32 @@
         return cls.from_dict(data)
 
+    def _deserialize_content(self, content_dict):
+        """Subclasses override this to restore real fields."""
+        pass  # default: do nothing
+
+
+    def _serialize_content(self):
+        """
+        Subclasses override to return all integrity-relevant fields.
+        Should include:
+        - all actual structured data
+        - comment (if meaningful)
+        - signature_data / certificate info (if present)
+        """
+        return {}
+
+    def canonical_content(self) -> str:
+        """Get canonical JSON string of content for fingerprinting."""
+        return self.canonicalize_content_dict(self._serialize_content())
+
     def _compute_fingerprint(self) -> str:
         """I recompute the entity's content fingerprint."""
-        seed = self.canonical_seed()
-        return hashlib.blake2s(seed.encode("utf-8"), digest_size=8).hexdigest().upper()
+        return hashlib.blake2s(self.canonical_content().encode("utf-8"), digest_size=8).hexdigest().upper()
 
     def _update_fingerprint(self) -> bool:
-        """
-        I update FlexOID if the content fingerprint changed.
-        """
         new_fp = self._compute_fingerprint()
-        if new_fp != self.fingerprint:
-            self.fingerprint = new_fp
-            self.flexo_id = FlexOID.safe_generate(self.domain_id,
-                                                  self.entity_type.value,
-                                                  self.state.value,
-                                                  self.text_seed,
-                                                  self.flexo_id.version)
-            return True
-        return False
-
-    def _transition(self, target_state: EntityState):
-        """
-        I am an internal helper for state transitions with version/fingerprint checks
-        and forward-only enforcement.
-        """
-
-        if target_state not in self.allowed_transitions():
-            raise ValueError(
-                f"Illegal state transition: {self.state.name} → {target_state.name}. "
-            )
-
-        # special case: marking obsolete
-        if target_state == EntityState.OBSOLETE:
-            self.flexo_id = self.flexo_id.with_state(EntityState.OBSOLETE.value)
-            return
-
-        self.state = target_state
+        changed = new_fp != self.fingerprint
+        self.fingerprint = new_fp
+        return changed
 
     # ───────────────────────────────────────────────────────────────
@@ -380,8 +376,8 @@
         """
         if self.state == EntityState.DRAFT:
-            new_fid = FlexOID.safe_generate(self.domain_id,
-                                            self.entity_type.value,
-                                            EntityState.APPROVED.value,
-                                            self.text_seed,
+            new_fid = FlexOID.safe_generate(domain_id=self.domain_id,
+                                            entity_type=self.entity_type.value,
+                                            state=EntityState.APPROVED.value,
+                                            text=self.text_seed,
                                             version=self.version
                                             )
@@ -401,5 +397,7 @@
 
         # Change only the trailing state letter (A → S)
+        old_id = self.flexo_id
         self.flexo_id = self.flexo_id.with_state(EntityState.APPROVED_AND_SIGNED.value)
+        self.flexo_id.origin = old_id
         return self
 
@@ -417,8 +415,8 @@
 
         new_fid = FlexOID.safe_generate(
-            self.domain_id,
-            self.entity_type.value,
-            EntityState.PUBLISHED.value,
-            self.text_seed,
+            domain_id=self.domain_id,
+            entity_type=self.entity_type.value,
+            state=EntityState.PUBLISHED.value,
+            text=self.text_seed,
             version=self.version
         )
@@ -435,5 +433,15 @@
             )
         if self.state != EntityState.OBSOLETE:
-            self._transition(EntityState.OBSOLETE)
+            new_fid = FlexOID.safe_generate(
+                domain_id=self.domain_id,
+                entity_type=self.entity_type.value,
+                state=EntityState.OBSOLETE.value,
+                text=self.text_seed,
+                version=self.version
+            )
+
+        self.origin = self.flexo_id
+        self.flexo_id = new_fid
+
         return self
 
@@ -442,8 +450,8 @@
         self.origin = str(self.flexo_id)
         self.flexo_id = FlexOID.clone_new_base(
-            self.domain_id,
-            self.entity_type.value,
-            EntityState.DRAFT.value,
-            self.text_seed,
+            domain_id=self.domain_id,
+            entity_type=self.entity_type.value,
+            state=EntityState.DRAFT.value,
+            text=self.text_seed,
         )
         return self
@@ -459,17 +467,7 @@
         Returns False if:
           - flexo_id format is invalid
-          - derived state/type mismatch the ID
-          - fingerprint doesn't match the canonical text seed
         """
         try:
             if not isinstance(entity.flexo_id, FlexOID):
-                return False
-
-            # Validate domain and ID coherence
-            if entity.domain_id != entity.flexo_id.domain_id:
-                return False
-            if entity.entity_type.value != entity.flexo_id.entity_type:
-                return False
-            if entity.state.value != entity.flexo_id.state_code:
                 return False
 
Index: flexoentity/flexo_signature.py
===================================================================
--- flexoentity/flexo_signature.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ flexoentity/flexo_signature.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -4,4 +4,5 @@
 from uuid import UUID
 from flexoentity import FlexoEntity, FlexOID, EntityType
+
 
 @dataclass
@@ -46,4 +47,13 @@
     public_cert_path: Optional[str] = None
 
+    def to_dict(self):
+        return {
+            "platform": self.platform,
+            "identifier": self.identifier,
+            "private_key_path": self.private_key_path,
+            "public_cert_path": self.public_cert_path
+        }
+
+
 @dataclass
 class FlexoSignature(FlexoEntity):
@@ -75,9 +85,11 @@
     def _serialize_content(self):
         return {
-            "signed_entity": self.signed_entity,
+            "signed_entity": str(self.signed_entity),
             "signer_id": str(self.signer_id),
             "signature_data": self.signature_data,
-            "certificate_reference": self.certificate_reference.to_dict(),
-            "certificate_thumbprint": self.certificate_thumbprint
+            "signature_type": self.signature_type,
+            # "certificate_reference": self.certificate_reference.to_dict(),
+            "certificate_thumbprint": self.certificate_thumbprint,
+            "comment": self.comment
         }
 
Index: flexoentity/id_factory.py
===================================================================
--- flexoentity/id_factory.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ flexoentity/id_factory.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -78,27 +78,13 @@
 from flexoentity import logger
 
-def canonical_seed(obj) -> str:
-    """
-    I transform *obj* into a deterministic, comparable text form.
-
-    I remove irrelevant formatting differences so that two equal
-    pieces of data always yield the same hash seed.
-
-    Rules:
-    - If *obj* is a string, I normalize whitespace.
-    - If *obj* is a dict, I JSON-encode it with sorted keys.
-    - If *obj* is an object, I recurse on its __dict__.
-    - Otherwise, I coerce *obj* to str().
-    """
-
-    if isinstance(obj, str):
-        text = " ".join(obj.split())
-        return text
-    if isinstance(obj, dict):
-        return json.dumps(obj, sort_keys=True, separators=(",", ":"))
-    if hasattr(obj, "__dict__"):
-        return canonical_seed(obj.__dict__)
-    return str(obj)
-
+def canonical_seed(text: str) -> str:
+    """Canonicalize identity-only text_seed."""
+    if not text:
+        return ""
+    # remove control characters
+    s = re.sub(r"[\t\r\n]+", " ", text)
+    # collapse multiple spaces
+    s = re.sub(r"\s+", " ", s)
+    return s.strip()
 
 class FlexOID(str):
@@ -346,5 +332,5 @@
 
     @staticmethod
-    def clone_new_base(domain: str, entity_type: str, state: str, text: str) -> "FlexOID":
+    def clone_new_base(domain_id: str, entity_type: str, state: str, text: str) -> "FlexOID":
         """
         I start a completely new lineage (version 1) for a derived entity.
@@ -352,5 +338,5 @@
         not share version history with its origin.
         """
-        return FlexOID.safe_generate(domain, entity_type, state, text, version=1)
+        return FlexOID.safe_generate(domain_id, entity_type, state, text, version=1)
 
     def to_dict(self) -> dict:
Index: tests/conftest.py
===================================================================
--- tests/conftest.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ tests/conftest.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -1,10 +1,8 @@
-# tests/stubs/single_choice_question.py
-from dataclasses import dataclass, field
 import pytest
 import platform
 from pathlib import Path
 from datetime import datetime
-from typing import List
-from flexoentity import FlexOID, FlexoEntity, EntityType, EntityState, Domain, get_signing_backend, CertificateReference
+from flexoentity import Domain, FlexoSignature
+from flexoentity import get_signing_backend, CertificateReference
 
 
@@ -18,70 +16,4 @@
     return FixedDate
 
-@dataclass
-class AnswerOption:
-    id: str
-    text: str
-    points: float = 0.0
-
-    def to_dict(self):
-        return {"id": self.id, "text": self.text, "points": self.points}
-
-    @classmethod
-    def from_dict(cls, data):
-        return cls(
-            id=data.get("id", ""),
-            text=data.get("text", ""),
-            points=data.get("points", 0.0)
-        )
-
-
-@dataclass
-class SingleChoiceQuestion(FlexoEntity):
-    """A minimal stub to test FlexoEntity integration."""
-    ENTITY_TYPE = EntityType.ITEM
-
-    text: str = ""
-    options: List[AnswerOption] = field(default_factory=list)
-
-    def __post_init__(self):
-        # If no FlexOID yet, generate a draft ID now.
-        if not getattr(self, "flexo_id", None):
-            self.flexo_id = FlexOID.safe_generate(
-                domain_id=self.domain_id,
-                entity_type=SingleChoiceQuestion.ENTITY_TYPE.value,     # 'I'
-                state=EntityState.DRAFT.value,        # 'D'
-                text=self.text_seed or self.text,
-                version=1,
-            )
-
-    @classmethod
-    def default(cls):
-        return cls()
-
-    def _serialize_content(self):
-        return {
-            "text": self.text,
-            "options": [opt.to_dict() for opt in self.options],
-        }
-
-    @property
-    def text_seed(self) -> str:
-        """Include answer options (and points) for deterministic ID generation."""
-
-        joined = "|".join(
-            f"{opt.text.strip()}:{opt.points}"
-            for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
-        )
-        return f"{self.text}{joined}"
-
-    @classmethod
-    def from_dict(cls, data):
-        obj = cls(text=data.get("text", ""),
-            options=[AnswerOption.from_dict(o) for o in data.get("options", [])],
-        )
-        # restore FlexoEntity core fields
-        if "flexo_id" in data:
-            obj.flexo_id = FlexOID.to_dict(data["flexo_id"])
-        return obj
 
 @pytest.fixture
@@ -92,11 +24,4 @@
                                  description="ALL ABOUT ARITHMETIC IN PYTHON")
 
-@pytest.fixture
-def sample_question(sample_domain):
-    q = SingleChoiceQuestion.with_domain_id(domain_id=sample_domain.domain_id,
-                                            text="What is 2 + 2?",
-                                            options=[])
-    q._update_fingerprint()
-    return q
 
 SYSTEM = platform.system()
@@ -181,2 +106,9 @@
     except Exception as e:
         pytest.skip(f"Backend unavailable or misconfigured: {e}")
+
+@pytest.fixture
+def sample_signature(sample_domain, cert_ref_linux):
+    return FlexoSignature.with_domain_id(domain_id="SIG", signed_entity=sample_domain,
+                                         certificate_reference=cert_ref_linux,
+                                         comment="This is a mock signature")
+
Index: tests/test_flexoid.py
===================================================================
--- tests/test_flexoid.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ tests/test_flexoid.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -111,20 +111,8 @@
 # ──────────────────────────────────────────────
 
-def test_canonical_seed_for_strings_and_dicts():
+def test_canonical_seed_for_strings():
     s1 = "  Hello   world "
     s2 = "Hello world"
     assert canonical_seed(s1) == canonical_seed(s2)
-
-    d1 = {"b": 1, "a": 2}
-    d2 = {"a": 2, "b": 1}
-    assert canonical_seed(d1) == canonical_seed(d2)
-
-    class Dummy:
-        def __init__(self):
-            self.x = 1
-            self.y = 2
-    obj = Dummy()
-    assert isinstance(canonical_seed(obj), str)
-
 
 # ──────────────────────────────────────────────
Index: tests/test_id_lifecycle.py
===================================================================
--- tests/test_id_lifecycle.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ tests/test_id_lifecycle.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -3,22 +3,17 @@
 
 
-# ──────────────────────────────────────────────────────────────────────────────
-# Tests adapted to use real SingleChoiceQuestion fixture instead of DummyEntity
-# ──────────────────────────────────────────────────────────────────────────────
+def test_initial_state(sample_domain):
+    assert sample_domain.state == EntityState.DRAFT
+    assert sample_domain.flexo_id.version == 1
+    assert FlexoEntity.verify_integrity(sample_domain)
 
-def test_initial_state(sample_question):
-    q = sample_question
-    assert q.state == EntityState.DRAFT
-    assert q.flexo_id.version == 1
-    assert FlexoEntity.verify_integrity(q)
-
-def test_approval_does_not_bump_version(sample_question):
-    q = sample_question
+def test_approval_does_not_bump_version(sample_domain):
+    q = sample_domain
     q.approve()
     assert q.state == EntityState.APPROVED
     assert q.flexo_id.version == 1
 
-def test_signing_does_not_bump_version(sample_question):
-    q = sample_question
+def test_signing_does_not_bump_version(sample_domain):
+    q = sample_domain
     q.approve()
     before = q.flexo_id
@@ -38,6 +33,6 @@
 
 
-def test_publish_does_not_bump_version(sample_question):
-    q = sample_question
+def test_publish_does_not_bump_version(sample_domain):
+    q = sample_domain
     q.approve()
     q.sign()
@@ -48,39 +43,35 @@
 
 
-def test_modify_content_changes_fingerprint(sample_question):
-    q = sample_question
-    q.text += "Rephrased content"  # simulate text change
-    changed = q._update_fingerprint()
+def test_modify_content_changes_fingerprint(sample_signature):
+    sample_signature.comment += "Rephrased content"  # simulate text change
+    changed = sample_signature._update_fingerprint()
     assert changed
 
 
-def test_no_version_bump_on_draft_edits(sample_question):
-    q = sample_question
-    q.text = "Minor draft edit"
-    q._update_fingerprint()
-    assert q.flexo_id.version == 1
+def test_no_version_bump_on_draft_edits(sample_signature):
+    sample_signature.comment = "Minor draft edit"
+    sample_signature._update_fingerprint()
+    assert sample_signature.flexo_id.version == 1
 
 
-def test_version_bump_after_edit_and_sign(sample_question):
-    q = sample_question
-    q.approve()
-    v1 = str(q.flexo_id)
-    q.text = "Changed content"
-    q.sign()
-    assert str(q.flexo_id) != v1
+def test_version_bump_after_edit_and_sign(sample_signature):
+    sample_signature.approve()
+    v1 = str(sample_signature.flexo_id)
+    sample_signature.comment = "Changed comment"
+    sample_signature.sign()
+    assert str(sample_signature.flexo_id) != v1
 
 
-def test_integrity_check_passes_and_fails(sample_question):
-    q = sample_question
-    q.approve()
-    assert FlexoEntity.verify_integrity(q)
+def test_integrity_check_passes_and_fails(sample_signature):
+    sample_signature.approve()
+    assert FlexoEntity.verify_integrity(sample_signature)
 
     # simulate tampering
-    q.text = "Tampered text"
-    assert not FlexoEntity.verify_integrity(q)
+    sample_signature.comment = "Tampered text"
+    assert not FlexoEntity.verify_integrity(sample_signature)
 
 
-def test_obsolete_state(sample_question):
-    q = sample_question
+def test_obsolete_state(sample_domain):
+    q = sample_domain
     q.approve()
     q.sign()
@@ -90,6 +81,6 @@
 
 
-def test_clone_new_base_resets_lineage(sample_question):
-    q = sample_question
+def test_clone_new_base_resets_lineage(sample_domain):
+    q = sample_domain
     q.approve()
     q.sign()
@@ -102,6 +93,6 @@
     assert q.flexo_id.version == 1
 
-def test_clone_new_base_sets_origin(sample_question):
-    q = sample_question
+def test_clone_new_base_sets_origin(sample_domain):
+    q = sample_domain
     q.approve()
     q.sign()
@@ -115,6 +106,6 @@
     assert q.flexo_id != old_id
 
-def test_mass_version_increments_until_obsolete(sample_question):
-    q = sample_question
+def test_mass_version_increments_until_obsolete(sample_domain):
+    q = sample_domain
     q.approve()
     for _ in range(FlexOID.MAX_VERSION - 1):
Index: tests/test_id_stress.py
===================================================================
--- tests/test_id_stress.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ tests/test_id_stress.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -9,6 +9,6 @@
 
 import pytest
-
-from flexoentity import FlexOID, EntityType, EntityState
+from uuid import uuid4
+from flexoentity import FlexOID, EntityType, EntityState, FlexoSignature
 
 logger = logging.getLogger(__name__)
@@ -66,17 +66,25 @@
     assert id1 == id2
 
+def test_massive_lifecycle_simulation(cert_ref_linux, sample_domain):
+    """
+    Generate 100 random FlexoSignatures, mutate content, run through lifecycle,
+    and ensure all FlexOIDs are unique and valid.
+    """
+    entities = []
 
-def test_massive_lifecycle_simulation(sample_question):
-    """
-    Generate 100 random SingleChoiceQuestions, simulate multiple edits and state transitions,
-    ensure all final IDs and fingerprints are unique and valid.
-    """
-    entities = [
-        copy.deepcopy(sample_question) for _ in range(100)
-    ]
+    for i in range(100):
+        sig = FlexoSignature.with_domain_id(
+            domain_id="SIGTEST",
+            signed_entity=sample_domain.flexo_id,
+            signer_id=uuid4(),
+            certificate_reference=cert_ref_linux,
+            comment=f"Initial signature #{i}"
+        )
+        entities.append(sig)
 
+    # Mutate + lifecycle transitions
     for i, e in enumerate(entities):
-        # random edit
-        e.text += f" updated #{i}"
+        # CONTENT CHANGE → fingerprint changes → hash → FlexOID.prefix changes
+        e.comment += f" updated-{i}"
         e._update_fingerprint()
 
@@ -88,4 +96,5 @@
             e.publish()
 
-    flexoids = [e.flexo_id for e in entities]
-    assert len(flexoids) == len(set(flexoids)), "Duplicate FlexOIDs after lifecycle simulation"
+    # Check ID uniqueness
+    flexoids = [str(e.flexo_id) for e in entities]
+    assert len(flexoids) == len(set(flexoids)), "Duplicate FlexOIDs detected"
Index: tests/test_persistance_integrity.py
===================================================================
--- tests/test_persistance_integrity.py	(revision 9a50e0baf26e6b6717034edef69def238882f3e1)
+++ tests/test_persistance_integrity.py	(revision ef964d8f15909f313336b5d702ebef7408122d6f)
@@ -6,64 +6,54 @@
 import pytest
 
-from flexoentity import EntityState, EntityType, Domain
+from flexoentity import Domain
+
 
 @pytest.fixture
-def approved_question():
-    """Provide a fully approved and published SingleChoiceQuestion for persistence tests."""
-    q = SingleChoiceQuestion(
-        domain=Domain(domain="GEN", entity_type=EntityType.DOMAIN, state=EntityState.DRAFT),
-        entity_type=None,  # SingleChoiceQuestion sets this internally to EntityType.ITEM
-        state=EntityState.DRAFT,
-        text="What is Ohm’s law?",
-        options=[
-            AnswerOption(id="OP1", text="U = R × I", points=1),
-            AnswerOption(id="OP2", text="U = I / R", points=0),
-            AnswerOption(id="OP3", text="R = U × I", points=0),
-        ],
-    )
-    q.approve()
-    q.sign()
-    q.publish()
-    return q
+def approved_domain(sample_domain):
+    """Provide a fully approved and published Domain for persistence tests."""
+    sample_domain.approve()
+    sample_domain.sign()
+    sample_domain.publish()
+    return sample_domain
 
 
-@pytest.mark.skip(reason="FlexOIDs regenerated on import; enable once JSON format is stable")
-def test_json_roundtrip_preserves_integrity(approved_question):
+def test_json_roundtrip_preserves_integrity(approved_domain):
     """
     Export to JSON and reload — ensure fingerprints and signatures remain valid.
     """
-    json_str = approved_question.to_json()
-    loaded = SingleChoiceQuestion.from_json(json_str)
+    json_str = approved_domain.to_json()
+    loaded = Domain.from_json(json_str)
 
     # Fingerprint and state should match — integrity must pass
-    assert SingleChoiceQuestion.verify_integrity(loaded)
+    assert Domain.verify_integrity(loaded)
 
     # Metadata should be preserved exactly
-    assert approved_question.fingerprint == loaded.fingerprint
-    assert approved_question.flexo_id == loaded.flexo_id
-    assert loaded.state == approved_question.state
+    assert approved_domain.fingerprint == loaded.fingerprint
+    assert approved_domain.flexo_id == loaded.flexo_id
+    assert loaded.state == approved_domain.state
 
-@pytest.mark.skip(reason="FlexOIDs regenerated on import; tampering detection not yet implemented")
-def test_json_tampering_detection(approved_question):
+
+def test_json_tampering_detection(approved_domain):
     """Tampering with content should invalidate fingerprint verification."""
-    json_str = approved_question.to_json()
+    json_str = approved_domain.to_json()
     tampered = json.loads(json_str)
-    tampered["text"] = "Tampered content injection"
+    tampered["content"]["fullname"] = "Tampered content injection"
     tampered_json = json.dumps(tampered)
 
-    loaded = SingleChoiceQuestion.from_json(tampered_json)
-    assert not SingleChoiceQuestion.verify_integrity(loaded)
+    loaded = Domain.from_json(tampered_json)
+    assert not Domain.verify_integrity(loaded)
 
-@pytest.mark.skip(reason="FlexOIDs regenerated on import; corruption detection not yet applicable")
-def test_json_file_corruption(approved_question, tmp_path):
+
+def test_json_file_corruption(approved_domain, tmp_path):
     """Simulate file corruption — integrity check must fail."""
     file = tmp_path / "question.json"
-    json_str = approved_question.to_json()
+    json_str = approved_domain.to_json()
+    print("JSON", json_str)
     file.write_text(json_str)
 
     # Corrupt the file (simulate accidental byte modification)
-    corrupted = json_str.replace("Ohm’s", "Omm’s")
+    corrupted = json_str.replace("ARITHMETIC", "ARITHM")
     file.write_text(corrupted)
 
-    loaded = SingleChoiceQuestion.from_json(file.read_text())
-    assert not SingleChoiceQuestion.verify_integrity(loaded)
+    loaded = Domain.from_json(file.read_text())
+    assert not Domain.verify_integrity(loaded)
