def evaluate(c):
    provenance_gate = bool(c.get("provenance_complete"))
    data_gate = bool(c.get("data_complete")) and c.get("sample_size",0) >= c.get("min_sample",10**9)
    definition_gate = (c.get("baseline_version") == c.get("observed_version")) and not bool(c.get("membership_rule_changed_midwindow"))
    window_gate = bool(c.get("window_compatible")) and bool(c.get("windows_rebaselined"))
    confounder_gate = c.get("confounder","NONE") == "NONE"
    composition_flag = c.get("composition_delta",0) >= 0.20
    behavior_flag = c.get("behavior_delta",0) >= 0.15
    state="UNKNOWN"; reason="UNCLASSIFIED"
    if not provenance_gate:
        state,reason="REJECTED","PROVENANCE_INCOMPLETE"
    elif not definition_gate or not window_gate:
        state,reason="REVIEW_REQUIRED","INCOMPATIBLE_DEFINITION_OR_WINDOW"
    elif not data_gate:
        state,reason="INSUFFICIENT_DATA","SAMPLE_OR_COVERAGE_INSUFFICIENT"
    elif not confounder_gate:
        state,reason="DRIFT_SUSPECTED","CONFOUNDER_OPEN"
    elif composition_flag and behavior_flag:
        state,reason="DRIFT_CONFIRMED","COMPOSITION_AND_BEHAVIOR_DIVERGED"
    elif composition_flag or behavior_flag:
        state,reason="DRIFT_SUSPECTED","PARTIAL_DRIFT_EVIDENCE"
    else:
        state,reason="FIT","BASELINE_COMPATIBLE"
    return {"provenance_gate":provenance_gate,"data_gate":data_gate,"definition_gate":definition_gate,"window_gate":window_gate,"confounder_gate":confounder_gate,"composition_flag":composition_flag,"behavior_flag":behavior_flag,"decision_state":state,"control_reason":reason}
