def evaluate(c):
    decisive=['service_tier','sli_id','sli_definition','slo_target','measurement_window','measurement_source','sla_commitment','support_severity','response_target_minutes','support_hours','escalation_path','staffing_owner','dependency_boundary','review_trigger','evidence_ref']
    if any(c.get(k) in (None,'',[]) for k in decisive):
        return _out('HOLD_EVIDENCE_MISSING','UNKNOWN','UNKNOWN','UNKNOWN','UNKNOWN','DECISIVE_EVIDENCE_MISSING')
    if not c.get('user_relevant_measurement'):
        return _out('HOLD_MEASUREMENT_INVALID','INVALID','UNKNOWN','UNKNOWN','UNKNOWN','SLI_NOT_USER_RELEVANT')
    if c.get('dependency_slo') is None:
        return _out('HOLD_DEPENDENCY_RISK','PASS','UNKNOWN','UNKNOWN','UNKNOWN','CRITICAL_DEPENDENCY_OBJECTIVE_UNKNOWN')
    if float(c.get('sla_commitment')) > min(float(c.get('slo_target')),float(c.get('dependency_slo'))):
        return _out('REJECT_SLA_OVERCOMMIT','PASS','PASS','CAPABILITY_EXCEEDED','DEFINED' if c.get('consequence_defined') else 'MISSING','SLA_STRICTER_THAN_VALIDATED_CAPABILITY')
    if c.get('sla_is_commercial') and not (c.get('sla_consequence') and c.get('consequence_defined')):
        return _out('BLOCKED_CONSEQUENCE_UNDEFINED','PASS','PASS','PASS','MISSING','COMMERCIAL_SLA_WITHOUT_CONSEQUENCE')
    if c.get('support_hours')=='24x7' and c.get('staffing_coverage')!='24x7':
        return _out('HOLD_SUPPORT_UNSTAFFED','PASS','UNSTAFFED','PASS','DEFINED','SUPPORT_PROMISE_EXCEEDS_STAFFING_COVERAGE')
    return _out('ADMISSIBLE','PASS','STAFFED','PASS','DEFINED','MEASURABLE_SERVICEABLE_AND_BOUNDED')

def _out(decision,measurement,support,dependency,consequence,reason):
    return {'decision_state':decision,'measurement_state':measurement,'support_state':support,'dependency_state':dependency,'consequence_state':consequence,'reason_code':reason}
