Pluggable persistence for permission rules.
A store is addressed as {module, ref} — ref is whatever the module
needs (an ETS table, a repo name, a pid). Session-scoped rules are tagged
with session_id and only returned for that session; :call-scoped
approvals are transient and never stored.
Summary
Callbacks
All unexpired candidate rules for a subject + session (global rules included).
Callbacks
@callback list(ref :: term()) :: {:ok, [GenAI.Approval.Permission.Rule.t()]}
@callback put(ref :: term(), GenAI.Approval.Permission.Rule.t()) :: :ok | {:error, term()}
@callback rules( ref :: term(), subject :: String.t() | nil, session_id :: String.t() | nil ) :: {:ok, [GenAI.Approval.Permission.Rule.t()]}
All unexpired candidate rules for a subject + session (global rules included).