CRITICAL = [
"lab_run_id","fixture_set_id","workflow_version","synthetic_item_id","event_sequence","actor_role","transition_id","expected_state","actual_state","approval_revision_ref","evidence_fixture_ref","side_effect_mode","idempotency_key","fault_injection","audit_event_ids","assertion_result","replay_ref","evidence_ref"]

def evaluate(c):
    missing=[k for k in CRITICAL if c.get(k) in (None,"",[],{})]
    evidence_complete=not missing
    side_effect_safe=c.get("side_effect_mode") in ("BLOCKED","NOOP","FAKE_ONLY")
    revision_binding_valid=c.get("approval_revision_ref")==c.get("active_revision_ref")
    duplicate=bool(c.get("duplicate_transition"))
    idempotency_safe=(not duplicate) or bool(c.get("idempotency_key"))
    assertion_ok=(c.get("assertion_result")=="PASS" and c.get("expected_state")==c.get("actual_state"))
    audit_complete=bool(c.get("audit_event_ids")) and bool(c.get("failed_event_recorded",True))
    replayable=bool(c.get("replay_ref")) and audit_complete
    legal_scope_ok=True
    if c.get("content_class")=="REGULATED":
        legal_scope_ok=(c.get("legal_review_required") is True and c.get("legal_review_state")=="APPROVED")
    elif c.get("legal_review_required") is True:
        legal_scope_ok=False

    if missing:
        state="HOLD_MISSING_EVIDENCE"
    elif not side_effect_safe:
        state="BLOCKED_SIDE_EFFECT"
    elif not revision_binding_valid:
        state="BLOCKED_STALE_APPROVAL"
    elif not idempotency_safe:
        state="BLOCKED_IDEMPOTENCY"
    elif not legal_scope_ok:
        state="BLOCKED_SCOPE"
    elif not assertion_ok:
        state="BLOCKED_ASSERTION"
    elif not audit_complete or not replayable:
        state="PARTIAL_AUDIT_GAP"
    else:
        state="READY_FOR_HUMAN_RELEASE_REVIEW"
    return {
      "state":state,
      "evidence_complete":evidence_complete,
      "side_effect_safe":side_effect_safe,
      "revision_binding_valid":revision_binding_valid,
      "idempotency_safe":idempotency_safe,
      "replayable":replayable
    }
