Files

58 lines
1.6 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from .config import Settings
@dataclass(frozen=True, slots=True)
class AuthorizationDecision:
level: str
read_only: bool
requires_confirmation: bool
reason: str
def classify_voice_authorization(
speaker_id: str | None,
confidence: float,
settings: Settings | None = None,
) -> AuthorizationDecision:
"""Map speaker identity confidence to a safety tier.
Voice identity is advisory. Dangerous changes still require explicit approval
elsewhere in the protocol.
"""
settings = settings or Settings()
if not speaker_id:
return AuthorizationDecision(
level="unknown",
read_only=True,
requires_confirmation=True,
reason="No enrolled speaker matched this utterance.",
)
if confidence >= settings.speaker_confirmed_threshold:
return AuthorizationDecision(
level="confirmed",
read_only=False,
requires_confirmation=False,
reason=f"Speaker {speaker_id} matched above confirmed threshold.",
)
if confidence >= settings.speaker_probable_threshold:
return AuthorizationDecision(
level="probable",
read_only=False,
requires_confirmation=True,
reason=f"Speaker {speaker_id} matched above probable threshold only.",
)
return AuthorizationDecision(
level="unknown",
read_only=True,
requires_confirmation=True,
reason=f"Speaker {speaker_id} confidence below probable threshold.",
)