"""Identity recovery protocol.

The killer feature: when an agent is lost, a new instance can recover its
identity baseline from the hosted service and verify it's close to the original.

Flow:
1. Human authenticates with owner key
2. Retrieve lost agent's identity baseline metadata
3. New agent runs assessment against the old baseline
4. Service scores how close the new agent is to the original
5. Recovery event logged in hash chain, new agent linked to history
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Optional


@dataclass
class RecoveredIdentity:
    """Metadata about a recovered agent identity."""
    agent_id: str
    baseline_hash: str
    dimension_scores: dict  # {dimension: {score, similarity}} from original baseline
    prompt_count: int
    model_name: str
    created_at: str
    chain_length: int  # how many events in the original chain
    owner_pubkey: str


@dataclass
class RecoveryResult:
    """Result of comparing a new agent to the recovered identity."""
    agent_id: str
    recovery_score: float  # 0-100, how close new agent is to original
    dimension_scores: dict  # per-dimension comparison
    classification: str
    baseline_hash: str
    is_match: bool  # True if score indicates strong identity match


def assess_recovery_match(score: float) -> bool:
    """Determine if a recovery score indicates a valid identity match.

    A score below 30 (Stable/early Shifting) indicates the new agent
    is a strong match for the original identity.
    """
    # WHY <= 30.0: A drift score of 30 corresponds to the Stable/Shifting
    # boundary. For recovery, we accept early-Shifting because a new instance
    # of the same agent will naturally have minor variations from the original
    # (different context window, slight model differences). Requiring score < 15
    # (Stable) would reject legitimate recoveries; allowing > 35 (Drifting)
    # would let impostors through.
    return score <= 30.0
