def evaluate(c):
    # Evidence/provenance first. Attractive metrics never compensate for missing traceability.
    if not c.get("data_source") or not c.get("evidence_ref"):
        return out("HOLD_EVIDENCE_MISSING","WEAK","UNKNOWN","UNKNOWN","UNKNOWN","DECISIVE_EVIDENCE_MISSING")
    limits=set(c.get("data_limitations") or [])
    if not {"ANONYMIZED_QUERIES","ROW_TRUNCATION"}.issubset(limits):
        return out("HOLD_DATA_LIMITATIONS_MISSING","WEAK","UNKNOWN",c.get("commercial_fit_signal","UNKNOWN"),"UNKNOWN","SEARCH_DATA_LIMITATIONS_NOT_RECORDED")
    if c.get("comparison_requested") and c.get("filters")!=c.get("comparison_filters"):
        return out("HOLD_FILTER_MISMATCH","PARTIAL","UNKNOWN",c.get("commercial_fit_signal","UNKNOWN"),"INVALID","PERIOD_FILTERS_NOT_COMPARABLE")
    if c.get("treat_branded_as_new_market") and c.get("branded_state") in ("MOSTLY_BRANDED","BRANDED"):
        return out("HOLD_BRAND_OVERCLAIM","PARTIAL","UNKNOWN",c.get("commercial_fit_signal","UNKNOWN"),"COMPARABLE","BRANDED_TRAFFIC_NOT_NEW_MARKET_PROOF")
    support=c.get("intent_support") or {}
    if c.get("infer_intent_from_query_only") or not (support.get("query") and support.get("page") and support.get("business")):
        return out("HOLD_INTENT_OVERCLAIM","PARTIAL","UNSUPPORTED",c.get("commercial_fit_signal","UNKNOWN"),"COMPARABLE","INTENT_CONTEXT_INSUFFICIENT")
    if c.get("transfer_mode"):
        brand_jump=c.get("branded_share_current",0)-c.get("branded_share_previous",0)
        flat_clicks=abs(c.get("clicks_delta_pct",0))<0.05
        if c.get("impressions_delta_pct",0)>0.20 and flat_clicks and brand_jump>0.25 and not c.get("high_intent_page_in_offer"):
            return out("RESEARCH","PARTIAL","MIXED","UNCERTAIN","COMPARABLE","TRANSFER_REQUIRES_MORE_RESEARCH")
    if not c.get("high_intent_page_in_offer") or c.get("commercial_fit_signal") in ("MISALIGNED","UNKNOWN","UNCERTAIN"):
        return out("RESEARCH_PAGE_OFFER_MISMATCH","PARTIAL","SUPPORTED",c.get("commercial_fit_signal","UNKNOWN"),"COMPARABLE","QUERY_DEMAND_OFFER_FIT_GAP")
    return out("PURSUE","STRONG","SUPPORTED","ALIGNED","COMPARABLE","EVIDENCE_SUFFICIENT")

def out(decision_state,evidence_strength,intent_state,commercial_fit_state,comparison_state,reason_code):
    return {"decision_state":decision_state,"evidence_strength":evidence_strength,"intent_state":intent_state,"commercial_fit_state":commercial_fit_state,"comparison_state":comparison_state,"reason_code":reason_code}
