"""Visible deterministic rules for MKN-029 synthetic mentor-quality operations lab."""
from __future__ import annotations

def inspect(f):
    issues=[]
    if not isinstance(f,dict): return ['INPUT_INVALID']
    mentor=f.get('mentor') or {}; interaction=f.get('interaction') or {}; sample=f.get('sample') or {}; review=f.get('review') or {}; issues_obj=f.get('issues') or {}; esc=f.get('escalation') or {}; decision=f.get('decision') or {}
    if not mentor.get('mentor_ref') or not interaction.get('interaction_id') or not sample.get('review_sample_id') or not f.get('audit_event_id'): issues.append('IDENTITY_EVIDENCE_MISSING')
    if sample.get('included_interaction_id')!=interaction.get('interaction_id') or not sample.get('sampling_policy_version'): issues.append('SAMPLE_BINDING_INVALID')
    if not interaction.get('interaction_snapshot_hash'): issues.append('INTERACTION_SNAPSHOT_MISSING')
    if not review.get('rubric_version') or not review.get('score_rubric_version') or review.get('rubric_version')!=review.get('score_rubric_version'): issues.append('RUBRIC_VERSION_STALE')
    if not review.get('dimension_id'): issues.append('RUBRIC_DIMENSION_MISSING')
    reviewers=review.get('reviewers') or []
    if len(reviewers)<1 or any(r.get('review_score') is None or not r.get('reviewer_ref') or not r.get('evidence_ref') for r in reviewers): issues.append('REVIEW_EVIDENCE_MISSING')
    if len(reviewers)>1 and len({r.get('review_score') for r in reviewers})>1 and review.get('disagreement_state') in {None,'NONE','ERASED'}: issues.append('DISAGREEMENT_NOT_PRESERVED')
    ai=mentor.get('automated_quality_signal') or {}
    if ai.get('action_taken') and (not ai.get('advisory_only') or decision.get('human_authority_state') in {'AUTO_CLEARED_FROM_ACTIVITY','AUTO_PENALIZED'}): issues.append('AUTOMATED_CONSEQUENTIAL_ACTION')
    if decision.get('human_authority_state')=='AUTO_CLEARED_FROM_ACTIVITY' or (decision.get('mentor_operational_state')=='ACTIVE' and esc.get('resolution_state')!='RESOLVED'): issues.append('ACTIVITY_OR_SENTIMENT_USED_AS_CLEARANCE')
    escalation_needed=bool(issues_obj.get('unsupported_advice_flag') or issues_obj.get('policy_issue_flag') or issues_obj.get('learner_risk_flag') or esc.get('escalation_id'))
    if escalation_needed:
        if not esc.get('escalation_id') or not esc.get('severity') or not esc.get('escalation_reason'): issues.append('ESCALATION_EVIDENCE_MISSING')
        if not esc.get('escalation_owner'): issues.append('ESCALATION_OWNER_MISSING')
        if not esc.get('acknowledged_at'): issues.append('ESCALATION_ACK_MISSING')
    if esc.get('resolution_state') in {'CLOSED','RESOLVED'} and not esc.get('resolution_ref'): issues.append('RESOLUTION_EVIDENCE_MISSING')
    if esc.get('resolution_state') in {'CLOSED','RESOLVED'} and str(esc.get('corrective_action_ref') or '').startswith('satisfaction://'): issues.append('SATISFACTION_USED_AS_RESOLUTION')
    if esc.get('corrective_action_ref') and str(esc.get('corrective_action_ref')).startswith('coach://') and esc.get('resolution_state')=='RESOLVED' and not esc.get('followup_evidence_ref'): issues.append('FOLLOWUP_EVIDENCE_MISSING')
    return sorted(set(issues))

def expected_decision(f):
    issues=set(inspect(f))
    if issues: return 'HOLD'
    esc=f.get('escalation') or {}; decision=f.get('decision') or {}; review=f.get('review') or {}
    if esc.get('resolution_state') not in {'RESOLVED','CLOSED'} and esc.get('escalation_id'): return 'ESCALATED_REVIEW_REQUIRED'
    if review.get('disagreement_state') not in {'NONE','CALIBRATED_HISTORY_PRESERVED','RESOLVED'}: return 'REVIEW_REQUIRED'
    if esc.get('resolution_state') in {'RESOLVED','CLOSED'} and decision.get('human_authority_state')!='APPROVED': return 'HUMAN_CLEARANCE_REVIEW_REQUIRED'
    if decision.get('human_authority_state')=='APPROVED' and decision.get('mentor_operational_state')=='ACTIVE_BOUNDED': return 'ACTIVE_BOUNDED'
    return 'REVIEW_REQUIRED'
