Refuse stale installed owner packages despite matching version metadata
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
tegwick 2026-09-09 23:02:29 +02:00
parent be42de7caf
commit 7a61383e59
4 changed files with 86 additions and 3 deletions

View file

@ -43,6 +43,33 @@ def install_claude(output: Path, source: Path, sha256: str, version: str) -> dic
"expected_version": version, "source": str(source)}
def verify_source_files(site: Path, mappings: list[tuple[Path, str, str]]) -> dict:
"""Refuse stale/missing/extra package contents even when versions match."""
expected = {}
for source, prefix, destination in mappings:
tracked = checked(["git", "-C", str(source), "ls-files", prefix]).splitlines()
if not tracked:
raise ValueError("owner package source mapping is empty")
for name in tracked:
relative = Path(destination) / Path(name).relative_to(prefix)
wanted = hashlib.sha256((source / name).read_bytes()).hexdigest()
installed = site / relative
if (not installed.is_file() or installed.is_symlink()
or hashlib.sha256(installed.read_bytes()).hexdigest() != wanted):
raise ValueError(f"owner package content mismatch: {relative}")
expected[relative.as_posix()] = wanted
actual = set()
for package in {Path(name).parts[0] for name in expected}:
for path in (site / package).rglob("*"):
if path.is_file() and "__pycache__" not in path.parts:
actual.add(path.relative_to(site).as_posix())
if actual != set(expected):
raise ValueError("owner package has unexpected installed files")
return {"files_verified": len(expected), "manifest_sha256": hashlib.sha256(
json.dumps(expected, sort_keys=True, separators=(",", ":")).encode()
).hexdigest()}
def build(output: Path, rein_source: Path, llm_source: Path,
claude_binary: Path | None = None, claude_sha256: str | None = None,
claude_version: str | None = None, *, owner_runtime: bool = False) -> dict:
@ -68,8 +95,10 @@ def build(output: Path, rein_source: Path, llm_source: Path,
output.mkdir(parents=True, exist_ok=False)
checked(["/usr/bin/python3", "-m", "venv", "--copies", "--without-pip", str(output)])
if owner_runtime:
refresh = [arg for name in revisions for arg in ("--refresh-package", name)]
checked(["uv", "sync", "--project", str(rein_source), "--frozen", "--no-editable",
"--no-dev", "--extra", "glas", "--extra", "llm", "--python", "/usr/bin/python3"],
"--no-dev", "--extra", "glas", "--extra", "llm", "--python", "/usr/bin/python3",
*refresh],
env={**os.environ, "UV_PROJECT_ENVIRONMENT": str(output)})
else:
checked(["uv", "pip", "install", "--python", str(output / "bin/python3"),
@ -93,6 +122,23 @@ def build(output: Path, rein_source: Path, llm_source: Path,
metadata["claude"] = install_claude(output, claude_binary, claude_sha256, claude_version)
metadata["source_revisions"] = revisions
if owner_runtime:
lock = json.loads((rein_source / "deploy/runtime-contract-lock.json").read_text())
sources = {x["distribution"]: (rein_source / x["source"]).resolve()
for x in lock["dependencies"]}
site = Path(checked([str(output / "bin/python3"), "-I", "-B", "-c",
"import sysconfig; print(sysconfig.get_path('purelib'))"]))
if not site.resolve().is_relative_to(output.resolve()):
raise ValueError("owner site-packages is outside artifact")
metadata["source_contents"] = verify_source_files(site, [
(rein_source, "rein_aharness", "rein_aharness"),
(sources["llm-connect"], "llm_connect", "llm_connect"),
(sources["glas-harness"], "src/glas_harness", "glas_harness"),
(sources["glas-harness"], "profiles", "glas_harness/data/profiles"),
(sources["glas-harness"], "registry/reins", "glas_harness/data/reins"),
(sources["sandboxer"], "src/sandboxer", "sandboxer"),
(sources["sandboxer"], "profiles", "sandboxer/data/profiles"),
(sources["sandboxer"], "extensions", "sandboxer/data/extensions"),
])
metadata["owner_runtime"] = True
metadata["runtime_contract"] = lock_report
metadata["uv_lock_sha256"] = hashlib.sha256(