diff --git a/tests/runtime/runtime_harness.py b/tests/runtime/runtime_harness.py
index 17e533c..4a9939c 100755
--- a/tests/runtime/runtime_harness.py
+++ b/tests/runtime/runtime_harness.py
@@ -65,6 +65,23 @@ def sha256(path: Path) -> str:
     return h.hexdigest()
 
 
+def zip_content_tree(path: Path) -> dict[str, str]:
+    """Return archive entry content identities independent of ZIP encoding details.
+
+    Python/zlib versions can produce different DEFLATE byte streams for the same
+    logical archive. Release verification therefore compares the shipped tree,
+    then installs the tracked dist bytes as the exact artifact under test.
+    """
+    result: dict[str, str] = {}
+    with zipfile.ZipFile(path) as archive:
+        for info in archive.infolist():
+            if info.is_dir():
+                continue
+            require(info.filename not in result, f"duplicate archive entry: {info.filename}")
+            result[info.filename] = hashlib.sha256(archive.read(info)).hexdigest()
+    return result
+
+
 def free_port() -> int:
     with socket.socket() as s:
         s.bind(("127.0.0.1", 0))
@@ -302,7 +319,7 @@ class RuntimeContext:
         candidate = self.work / f"{self.theme}.zip"
         sh([sys.executable, str(ROOT / "tools" / "theme_factory.py"), "pack", str(container), str(candidate)], timeout=180)
         if releaseish and dist.exists():
-            require(sha256(candidate) == sha256(dist), f"release candidate tree does not equal dist/{self.theme}.zip")
+            require(zip_content_tree(candidate) == zip_content_tree(dist), f"release candidate tree does not equal dist/{self.theme}.zip")
             shutil.copy2(dist, candidate)
         return candidate
 
diff --git a/tests/verification/test_verification_engine.py b/tests/verification/test_verification_engine.py
index 3810108..8029fce 100644
--- a/tests/verification/test_verification_engine.py
+++ b/tests/verification/test_verification_engine.py
@@ -287,6 +287,26 @@ def test_runtime_candidate_zip_excludes_only_declared_non_shipping_metadata():
         shutil.rmtree(theme, ignore_errors=True)
 
 
+def test_runtime_release_tree_comparison_ignores_zip_compression_bytes(tmp_path):
+    import zipfile
+
+    runtime = _load_runtime_module("runtime_zip_tree_canary")
+    stored = tmp_path / "stored.zip"
+    deflated = tmp_path / "deflated.zip"
+    changed = tmp_path / "changed.zip"
+    payload = b"same logical release tree\n" * 64
+    for path, compression, data in (
+        (stored, zipfile.ZIP_STORED, payload),
+        (deflated, zipfile.ZIP_DEFLATED, payload),
+        (changed, zipfile.ZIP_DEFLATED, payload + b"changed"),
+    ):
+        with zipfile.ZipFile(path, "w", compression=compression) as archive:
+            archive.writestr("united-pets/style.css", data)
+    assert runtime.sha256(stored) != runtime.sha256(deflated)
+    assert runtime.zip_content_tree(stored) == runtime.zip_content_tree(deflated)
+    assert runtime.zip_content_tree(stored) != runtime.zip_content_tree(changed)
+
+
 def _load_runtime_module(name: str):
     import sys
     spec = importlib.util.spec_from_file_location(name, ROOT / "tests" / "runtime" / "runtime_harness.py")
