"""Chronicle CloudEvents client. Optional per GSAP ยง1.4.""" import hashlib, json, logging from datetime import datetime, UTC import httpx from gsap_broker.settings import settings logger = logging.getLogger(__name__) async def emit(kind: str, payload: dict) -> str: url = settings.chronicle_webhook_url if not url: return "" try: event_json = json.dumps({"kind": kind, **payload}, sort_keys=True, default=str) cid = "sha256:" + hashlib.sha256(event_json.encode()).hexdigest() async with httpx.AsyncClient(timeout=5.0) as client: await client.post(url, json={ "pusher": {"login": payload.get("principal_did", settings.broker_did)}, "ref": f"refs/gsap/{kind}", "repository": {"full_name": "gsap-broker/governance"}, "commits": [{"message": f"{kind}: {json.dumps(payload, default=str)}"}], }, headers={"X-Forgejo-Event": "push"}) return cid except Exception as e: logger.warning(f"Chronicle emit failed: {kind}: {e}") return ""