Index: flexoentity/flexo_entity.py
===================================================================
--- flexoentity/flexo_entity.py	(revision 02d288d33183db0124582a151433ccd6cf55cac7)
+++ flexoentity/flexo_entity.py	(revision 4ceca5724cee9fc801f725e205ea1281ea7dc908)
@@ -146,5 +146,5 @@
         """
        
-        self.flexo_id = FlexOID.generate(self.domain_code(),
+        self.flexo_id = FlexOID.safe_generate(self.domain_code(),
                                          self.etype.short(),
                                          self.state.short(),
@@ -221,5 +221,5 @@
         if new_sig != self.signature:
             self.signature = new_sig
-            self.flexo_id = FlexOID.generate(self.domain_code(),
+            self.flexo_id = FlexOID.safe_generate(self.domain_code(),
                                              self.etype.short(),
                                              self.state.short(),
@@ -261,4 +261,13 @@
         self.updated_at = datetime.now(UTC)
 
+    def lineage(self, repo):
+        """Return full ancestry chain [origin → ... → self]."""
+        chain = [self]
+        current = self
+        while current.origin and current.origin in repo:
+            current = repo[current.origin]
+            chain.insert(0, current)
+        return chain
+
     def approve(self):
         """
@@ -268,5 +277,5 @@
         if self.state == EntityState.DRAFT:
             new_version = self.flexo_id.version + 1
-            new_fid = FlexOID.generate(self.domain_code(),
+            new_fid = FlexOID.safe_generate(self.domain_code(),
                 self.etype.short(),
                 EntityState.APPROVED.short(),
@@ -294,4 +303,5 @@
     def clone_new_base(self):
         """Start new lineage when obsolete."""
+        self.origin = str(self.flexo_id)
         self.flexo_id = FlexOID.clone_new_base(
             self.domain_code(),
Index: flexoentity/id_factory.py
===================================================================
--- flexoentity/id_factory.py	(revision 02d288d33183db0124582a151433ccd6cf55cac7)
+++ flexoentity/id_factory.py	(revision 4ceca5724cee9fc801f725e205ea1281ea7dc908)
@@ -80,5 +80,5 @@
     @staticmethod
     def _blake_hash(text: str) -> str:
-        """Return a 6-hex BLAKE2s digest."""
+        """Return a 12-hex BLAKE2s digest."""
         return hashlib.blake2s(text.encode("utf-8"), digest_size=6).hexdigest().upper()  # 6 bytes → 12 hex
 
@@ -310,5 +310,5 @@
         - Used when creating "clones" or "variants" that should not share version history.
         """
-        return FlexOID.generate(domain, etype, estate, text, version=1)
+        return FlexOID.safe_generate(domain, etype, estate, text, version=1)
 
     def __str__(self):
Index: tests/test_id_lifecycle.py
===================================================================
--- tests/test_id_lifecycle.py	(revision 02d288d33183db0124582a151433ccd6cf55cac7)
+++ tests/test_id_lifecycle.py	(revision 4ceca5724cee9fc801f725e205ea1281ea7dc908)
@@ -94,4 +94,16 @@
     assert q.flexo_id.version == 1
 
+def test_clone_new_base_sets_origin(radio_question):
+    q = radio_question
+    q.approve()
+    q.sign()
+    q.publish()
+    old_id = str(q.flexo_id)
+    q.obsolete()
+    q.clone_new_base()
+    assert q.origin == old_id
+    assert q.state == EntityState.DRAFT
+    assert q.flexo_id.version == 1
+    assert q.flexo_id != old_id
 
 def test_mass_version_increments_until_obsolete(radio_question):
Index: tests/test_id_stress.py
===================================================================
--- tests/test_id_stress.py	(revision 02d288d33183db0124582a151433ccd6cf55cac7)
+++ tests/test_id_stress.py	(revision 4ceca5724cee9fc801f725e205ea1281ea7dc908)
@@ -14,5 +14,5 @@
 def test_bulk_generation_uniqueness(domain):
     """
-    Generate 10,000 IDs and ensure uniqueness using safe_generate().
+    Generate 100,000 IDs and ensure uniqueness using safe_generate().
     If a collision occurs, safe_generate() must resolve it automatically
     via salt + date adjustment.
@@ -20,5 +20,5 @@
     etype = EntityType.QUESTION
     estate = EntityState.DRAFT
-    seeds = [f"question {i}" for i in range(4000000)]
+    seeds = [f"question {i}" for i in range(100000)]
 
     # Simulate a simple in-memory repository for collision detection
