Changeset 0b4a5e6 in flexoentity
- Timestamp:
- 10/19/25 14:50:53 (3 months ago)
- Branches:
- master
- Children:
- 12d7663
- Parents:
- 59342ce
- Files:
-
- 3 edited
-
flexoentity/flexo_entity.py (modified) (1 diff)
-
flexoentity/id_factory.py (modified) (1 diff)
-
tests/test_persistance_integrity.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
flexoentity/flexo_entity.py
r59342ce r0b4a5e6 263 263 @staticmethod 264 264 def verify_integrity(entity) -> bool: 265 """ 266 Verify *state-aware* integrity. 267 268 This method validates that the entity's stored digital signature 269 matches a freshly recalculated one, based on the combination of: 270 271 text_seed + current lifecycle state (one-letter code) 272 273 Returns 274 ------- 275 bool 276 True if the entity's *state and content* are unchanged, 277 False if either was altered or corrupted. 278 """ 279 seed = canonical_seed(f"{entity.text_seed}:{entity.state.short()}") 280 recalculated_sig = hashlib.blake2s( 281 seed.encode("utf-8"), digest_size=8 282 ).hexdigest().upper() 283 284 return recalculated_sig == entity.flexo_id.signature 285 286 @staticmethod 287 def verify_content_integrity(entity) -> bool: 288 """ 289 Verify *content-only* integrity (ignores lifecycle state). 290 291 This method checks whether the stored entity's signature matches 292 a fresh hash of its text seed alone. It does not include the 293 lifecycle state in the fingerprint. 294 295 Returns 296 ------- 297 bool 298 True if the text content has not been altered, 299 False if it differs from the original content. 300 """ 301 seed = canonical_seed(entity.text_seed) 302 recalculated_sig = hashlib.blake2s( 303 seed.encode("utf-8"), digest_size=8 304 ).hexdigest().upper() 305 return recalculated_sig == entity.flexo_id.signature 265 # --- inhaltlicher (kryptographischer) Check --- 266 # Hash ohne State, Signatur mit State 267 hash_seed = canonical_seed(f"{entity.domain}:{entity.etype.short()}:{entity.text_seed}") 268 sig_seed = f"{hash_seed}:{entity.state.short()}" 269 270 expected_sig = hashlib.blake2s(sig_seed.encode("utf-8"), digest_size=8).hexdigest().upper() 271 return expected_sig == entity.flexo_id.signature 306 272 307 273 def allowed_transitions(self) -> list[str]: -
flexoentity/id_factory.py
r59342ce r0b4a5e6 89 89 raise RuntimeError("Too many collisions; adjust hash length or logic.") 90 90 91 # ──────────────────────────────────────────────────────────────────────────92 91 @staticmethod 93 92 def generate(domain: str, etype: str, estate: str, text: str, 93 version: int = 1, enforce_unique=True): 94 """ 95 Generate a deterministic Flex-O ID. 96 97 - The hash (and therefore prefix) depends only on domain, etype, and text. 98 → Prefix stays stable across state changes. 99 - The signature still includes the state for audit integrity. 100 """ 101 102 if not (1 <= version <= FlexOID.MAX_VERSION): 103 raise ValueError(f"Version {version} exceeds limit; mark obsolete.") 104 105 date_part = datetime.now(timezone.utc).strftime("%y%m%d") 106 107 # state-independent hash seed → prefix stability 108 hash_seed = canonical_seed(f"{domain}:{etype}:{text}") 109 base_hash = FlexOID._blake_hash(hash_seed) 110 unique_hash = ( 111 FlexOID._ensure_unique(base_hash, version) if enforce_unique else base_hash 112 ) 113 114 ver_part = f"{version:03d}{estate}" 115 flexo_id_str = f"{domain}-{etype}{date_part}-{unique_hash}@{ver_part}" 116 117 # state-dependent signature → per-state integrity 118 sig_seed = f"{hash_seed}:{estate}" 119 signature = hashlib.blake2s(sig_seed.encode("utf-8"), digest_size=8).hexdigest().upper() 120 121 return FlexOID(flexo_id_str, signature) # ────────────────────────────────────────────────────────────────────────── 122 123 124 @staticmethod 125 def generate_old(domain: str, etype: str, estate: str, text: str, 94 126 version: int = 1, enforce_unique = True): 95 127 """ -
tests/test_persistance_integrity.py
r59342ce r0b4a5e6 40 40 assert not FlexoEntity.verify_integrity(loaded) 41 41 42 # For state-aware systems, content-only integrity is *not applicable* unless regenerated43 # (i.e., the stored signature is not purely text-based). So we only assert the failure is detected.44 assert not FlexoEntity.verify_content_integrity(loaded)45 46 42 assert approved_entity.flexo_id.signature == loaded.flexo_id.signature 47 43 assert approved_entity.flexo_id == loaded.flexo_id
Note:
See TracChangeset
for help on using the changeset viewer.
