Ryker_Feng 41658c5ff4
feat(skills): add skill review quality gate (#4037)
* feat(skills): add skill review quality gate

* fix(skills): skip review eval fixtures in CI

* fix(skills): ignore review eval fixtures in bundled scans

* fix(skill-review): harden review gate boundaries

* fix(skills): address skill review gate feedback
2026-07-11 15:58:07 +08:00

34 lines
1.1 KiB
Python

"""Canonical package digest for review snapshots."""
from __future__ import annotations
import hashlib
from typing import Any
from deerflow.skills.review.models import normalize_relative_path
def compute_package_digest(snapshot: dict[str, Any]) -> str:
"""Return a host-path-independent SHA-256 digest for a package snapshot."""
records: list[bytes] = []
for file_entry in snapshot.get("files", []):
path = normalize_relative_path(str(file_entry["path"]))
kind = str(file_entry.get("kind") or "unknown")
size = int(file_entry.get("size") or 0)
content_digest = str(file_entry.get("sha256") or "")
record = b"\0".join(
[
kind.encode("utf-8"),
path.encode("utf-8"),
str(size).encode("ascii"),
content_digest.encode("ascii"),
]
)
records.append(record)
h = hashlib.sha256()
for record in sorted(records):
h.update(len(record).to_bytes(8, "big"))
h.update(record)
return f"sha256:{h.hexdigest()}"