Files
CelerisLab/tests/validation/source_provenance.py
T
ClaudeandClaude Opus 5.5 f02355a2b7 test: LES a135252 guard tests use the pinned tree, not today's src
The a135252 manifest is historical qualification: it pins the committed
corrected tree at a135252. The guard is correct; the four tests used the
current working tree as the 'pinned' fixture, so 87c3a31's jets.py change
broke them. Fixtures are now materialized from a135252 with git; the
corrected acceptance, baseline rejection, four tamper rejections and the
reversed-header baseline control are unchanged. A new test records that
the guard refuses today's src where it differs from the pin.

Missing history skips with the reason, or fails when
CELERIS_REQUIRE_HISTORY=1 (release gating) via history_unavailable().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:27:13 +00:00

71 lines
2.9 KiB
Python

"""Record runtime checkout identity separately from the reviewed source origin."""
import subprocess
def checkout_provenance(repo):
"""Require a Git checkout; never label changed-source runs as historical evidence."""
revision = subprocess.check_output(
["git", "-C", str(repo), "rev-parse", "HEAD"], text=True
).strip()
dirty = subprocess.check_output(
["git", "-C", str(repo), "status", "--porcelain", "--untracked-files=normal"],
text=True,
)
return dict(checkout_revision=revision, checkout_dirty=bool(dirty))
class HistoryUnavailable(RuntimeError):
"""The clone cannot show the recorded commit (no git, shallow clone, installed copy)."""
def historical_sha256(repo, commit, paths):
"""SHA-256 of each path as stored in `commit`, read with git, never from the working tree.
Raises HistoryUnavailable when git or the commit object is missing, so callers can
report an unchecked integrity record explicitly instead of passing or failing silently.
"""
import hashlib
git = ["git", "-C", str(repo)]
try:
subprocess.run([*git, "cat-file", "-e", f"{commit}^{{commit}}"], check=True,
capture_output=True)
except (OSError, subprocess.CalledProcessError) as error:
raise HistoryUnavailable(f"commit {commit} is not available in {repo}") from error
digests = {}
for path in paths:
try:
blob = subprocess.run([*git, "show", f"{commit}:{path}"], check=True,
capture_output=True).stdout
except subprocess.CalledProcessError as error:
raise ValueError(f"{path} is not part of {commit}") from error
digests[path] = hashlib.sha256(blob).hexdigest()
return digests
def historical_tree(repo, commit, prefix="src"):
"""Tracked file names under `prefix` at `commit` (HistoryUnavailable if missing)."""
historical_sha256(repo, commit, [])
return subprocess.check_output(["git", "-C", str(repo), "ls-tree", "-r", "--name-only",
commit, "--", prefix], text=True).splitlines()
def historical_files(repo, commit, paths, dest):
"""Write each path as stored in `commit` under `dest` (HistoryUnavailable if missing)."""
from pathlib import Path
historical_sha256(repo, commit, [])
for path in paths:
target = Path(dest) / path
target.parent.mkdir(parents=True, exist_ok=True)
target.write_bytes(subprocess.run(["git", "-C", str(repo), "show", f"{commit}:{path}"],
check=True, capture_output=True).stdout)
def history_unavailable(testcase, error):
"""Skip with the reason, or fail when CELERIS_REQUIRE_HISTORY=1 (release gating)."""
import os
message = f"historical integrity NOT checked: {error}"
if os.environ.get("CELERIS_REQUIRE_HISTORY") == "1":
raise AssertionError(message)
testcase.skipTest(message)