Manifests and receipts unchanged. Each of the 8 group-A identity tests now extracts its manifest's recorded commit and verifies hashes there instead of against the current checkout. Tamper assertions and runner source refusals are kept; missing recorded history is an explicit failure, not a skip or repin.
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
"""Check historical source manifests against their own recorded commit, not today's checkout."""
|
|
|
|
import io
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tarfile
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _require(commit):
|
|
"""Missing recorded history is an explicit failure, never a skip or a repin."""
|
|
found = subprocess.run(
|
|
["git", "-C", str(ROOT), "cat-file", "-e", commit + "^{commit}"],
|
|
capture_output=True,
|
|
)
|
|
if found.returncode:
|
|
raise AssertionError(
|
|
f"Required history missing: commit {commit} is not in this clone; "
|
|
"fetch it instead of repinning or substituting"
|
|
)
|
|
|
|
|
|
def tracked(commit, prefix="src"):
|
|
"""Tracked paths under prefix at the recorded commit."""
|
|
_require(commit)
|
|
return set(
|
|
subprocess.check_output(
|
|
["git", "-C", str(ROOT), "ls-tree", "-r", "--name-only", commit, prefix],
|
|
text=True,
|
|
).splitlines()
|
|
)
|
|
|
|
|
|
def historical_tree(commit, dest):
|
|
"""Extract the tracked tree of the recorded commit into dest."""
|
|
_require(commit)
|
|
archive = subprocess.check_output(
|
|
["git", "-C", str(ROOT), "archive", "--format=tar", commit]
|
|
)
|
|
dest = Path(dest)
|
|
dest.mkdir(parents=True, exist_ok=True)
|
|
extra = {"filter": "data"} if hasattr(tarfile, "data_filter") else {}
|
|
with tarfile.open(fileobj=io.BytesIO(archive)) as tar:
|
|
tar.extractall(dest, **extra)
|
|
return dest
|