""" Code Receipts — PATCH_RECEIPT_V1 ledger Every generated patch gets an immutable receipt with: - frame hashes that informed it - audio chunk hashes - speaker segments - retrieval docs - reason codes - uncertainty """ import json import os import time from pathlib import Path from typing import Optional RECEIPT_DIR = Path(os.getenv("RECEIPT_DIR", "/data/receipts" if Path("/data").exists() else "data/receipts")) RECEIPT_DIR.mkdir(parents=True, exist_ok=True) def save_receipt(receipt: dict) -> str: """Save receipt to disk. Returns the file path.""" receipt_id = receipt.get("patch_hash", str(int(time.time() * 1000))) path = RECEIPT_DIR / f"{receipt_id}.json" path.write_text(json.dumps(receipt, indent=2, default=str)) return str(path) def list_receipts(limit: int = 50) -> list: """List recent receipts.""" files = sorted(RECEIPT_DIR.glob("*.json"), key=lambda f: f.stat().st_mtime, reverse=True) receipts = [] for f in files[:limit]: receipts.append(json.loads(f.read_text())) return receipts def get_receipt(receipt_id: str) -> Optional[dict]: path = RECEIPT_DIR / f"{receipt_id}.json" if not path.exists(): return None return json.loads(path.read_text())