#!/usr/bin/env python3 """Reject modifications to accepted Architecture Decision Records.""" from __future__ import annotations import argparse import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] ADR_PREFIX = "docs/adr/ADR-" def _git(*args: str) -> str: return subprocess.check_output( ["git", *args], cwd=ROOT, text=True, stderr=subprocess.DEVNULL, ).strip() def _exists_on(base: str, path: str) -> bool: try: _git("cat-file", "-e", f"{base}:{path}") return True except subprocess.CalledProcessError: return False def find_modified_adrs(base: str) -> list[str]: try: diff_out = _git("diff", "--name-only", f"{base}...HEAD", "--", "docs/adr/") except subprocess.CalledProcessError: return [] modified: list[str] = [] for rel in diff_out.splitlines(): if not rel.startswith(ADR_PREFIX) or not rel.endswith(".md"): continue if _exists_on(base, rel): modified.append(rel) return sorted(modified) def run_check(base: str = "origin/main") -> int: modified = find_modified_adrs(base) if modified: print("Immutable ADR violation — accepted records cannot be edited:") for path in modified: print(f" error: {path}") print( "\nReversal or refinement → new ADR-NNNN file. " "Never edit an existing ADR-*.md." ) return 1 print(f"ADR immutability OK (base {base})") return 0 def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--base", default="origin/main", help="Git ref to compare against (default: origin/main)", ) args = parser.parse_args() sys.exit(run_check(base=args.base)) if __name__ == "__main__": main()