"""Async wrapper around the singleton PolicyEngine. F-15 remediation: the global ``POLICY`` reference is now guarded by a lock so concurrent FastAPI handlers can't race on init. """ from __future__ import annotations import logging import threading from typing import Any, Optional from backend.events.emitter import emit_policy log = logging.getLogger(__name__) _POLICY: Optional[Any] = None _policy_lock = threading.Lock() def init(policy_engine: Any) -> None: """Register the singleton policy engine.""" global _POLICY with _policy_lock: _POLICY = policy_engine def _get() -> Any: """Return the singleton, raising a clear error if init() was never called.""" with _policy_lock: if _POLICY is None: raise RuntimeError("policy engine not initialised — call policy.api.init() first") return _POLICY async def set_override(data: dict) -> dict: """Set ``data['key'] = data['value']`` on the singleton policy engine.""" eng = _get() eng.set_override(data["key"], data["value"]) await emit_policy(data["key"], data["value"]) return {"status": "ok"} async def clear_override(data: dict) -> dict: """Clear ``data['key']`` from the singleton policy engine.""" eng = _get() eng.clear_override(data["key"]) await emit_policy(data["key"], None) return {"status": "cleared"}