def _recommend(c):
    required=['capability_id','venture_scope','tenancy_model','isolation_level','change_cadence','data_sensitivity','failure_domain','owner','shared_cost','marginal_cost','migration_cost','coupling_score','serviceability_state','evidence_ref','provenance_ref']
    if any(c.get(k) is None or c.get(k)=='' for k in required): return 'UNKNOWN'
    if c.get('authority_conflict'): return 'DISPUTED'
    if c.get('evidence_age_days',0)>90: return 'STALE'
    if c.get('material_change_not_recomputed'): return 'PARTIAL'
    if c.get('serviceability_state')!='SERVICEABLE': return 'HOLD'
    if c['data_sensitivity']=='RESTRICTED' or c['isolation_level']=='DEDICATED' or c['failure_domain']=='DEDICATED': return 'SILO'
    if c['data_sensitivity']=='HIGH' or c['isolation_level']=='LOGICAL' or c['failure_domain']=='PARTITIONED' or c['change_cadence']=='INDEPENDENT_DAILY': return 'BRIDGE'
    if float(c['shared_cost']) > 2*float(c['migration_cost']) and float(c['coupling_score'])<=4: return 'SILO'
    return 'SHARED'

def evaluate(case):
    if case.get('policy_blocked'):
        return {'overall_state':'BLOCKED','decision_vector':{},'shared_count':0,'bridge_count':0,'silo_count':0,'total_shared_cost':0,'total_migration_cost':0,'control_reason':'POLICY_BLOCK'}
    vector={}; typed=[]; mismatch=False
    total_shared=0; total_migration=0
    for c in case['capabilities']:
        rec=_recommend(c); vector[c.get('capability_id','UNKNOWN')]=rec; typed.append(rec)
        total_shared += float(c.get('shared_cost') or 0); total_migration += float(c.get('migration_cost') or 0)
        if rec in {'SHARED','BRIDGE','SILO'} and c.get('tenancy_model')!=rec: mismatch=True
    precedence=['DISPUTED','STALE','PARTIAL','HOLD','UNKNOWN']
    overall=None
    for s in precedence:
        if s in typed: overall=s; break
    if overall is None and mismatch: overall='PIVOT_REQUIRED'
    if overall is None:
        active=set(typed)
        if len(active)>1: overall='ACCEPTED_MIXED'
        elif active=={'SHARED'}: overall='ACCEPTED_SHARED'
        elif active=={'BRIDGE'}: overall='ACCEPTED_BRIDGE'
        elif active=={'SILO'}: overall='ACCEPTED_SILO'
        else: overall='HOLD'
    control='ALL_GATES_SATISFIED'
    if overall=='PIVOT_REQUIRED': control='PROPOSED_MODEL_MISMATCH'
    elif overall in {'DISPUTED','STALE','PARTIAL','HOLD','UNKNOWN','BLOCKED'}: control=overall+'_EVIDENCE_GATE'
    return {
      'overall_state':overall,
      'decision_vector':vector,
      'shared_count':sum(v=='SHARED' for v in vector.values()),
      'bridge_count':sum(v=='BRIDGE' for v in vector.values()),
      'silo_count':sum(v=='SILO' for v in vector.values()),
      'total_shared_cost':round(total_shared,2),
      'total_migration_cost':round(total_migration,2),
      'control_reason':control
    }
