#!/usr/bin/env python3
"""Verify the immutable Base V3 source/build/test snapshot.

Authority DAG root: this snapshot contains only Base source, build, test, and
release-gate inputs. Mutable migration ledgers and operations outputs are
explicitly forbidden.
"""
from __future__ import annotations
import hashlib
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
MANIFEST = ROOT / "ci/manifests/base-v3-remediation-source.sha256"
FORBIDDEN_PREFIXES = ("v3-migration/", "v3-operations/")
ALLOWED_PREFIXES = ("v3-src/", "ci/", "pr8/pilot/")


def verify(root: Path = ROOT, manifest: Path = MANIFEST) -> list[str]:
    errors: list[str] = []
    rows = []
    for number, line in enumerate(manifest.read_text(encoding="utf-8").splitlines(), 1):
        if not line.strip():
            continue
        parts = line.split("  ", 1)
        if len(parts) != 2 or len(parts[0]) != 64:
            errors.append(f"malformed manifest row {number}")
            continue
        rows.append(parts)
    paths = [relative for _, relative in rows]
    if len(paths) != len(set(paths)):
        errors.append("duplicate manifest paths")
    for expected, relative in rows:
        if relative.startswith(FORBIDDEN_PREFIXES):
            errors.append(f"mutable downstream authority forbidden from Base snapshot: {relative}")
        if not relative.startswith(ALLOWED_PREFIXES):
            errors.append(f"path outside Base source/build/test scope: {relative}")
        path = root / relative
        if not path.is_file():
            errors.append(f"missing {relative}")
        elif hashlib.sha256(path.read_bytes()).hexdigest() != expected:
            errors.append(f"hash drift {relative}")
    return errors


def main() -> None:
    errors = verify()
    if errors:
        raise SystemExit("Base V3 source snapshot mismatch: " + "; ".join(errors))
    count = sum(bool(line.strip()) for line in MANIFEST.read_text().splitlines())
    print(f"verified immutable Base V3 source/build/test snapshot: {count} files; zero overrides")

if __name__ == "__main__":
    main()
