ALLOWED={"READY","PARTIAL","FALLBACK","UNSUPPORTED","HOLD"}
MISSING={"UNKNOWN","DISPUTED","STALE","MISSING","UNPROVEN",None,""}

def _known(c,key): return c.get(key) not in MISSING

def _cap_states(c):
    if not c.get("secure_context",False):
        return {k:"FAIL" for k in c.get("required_capabilities",[])}
    states={}
    if "INSTALL" in c.get("required_capabilities",[]):
        states["INSTALL"]="READY" if c.get("install_surface") in {"AVAILABLE","USER_AVAILABLE"} else "FAIL"
    if "OFFLINE" in c.get("required_capabilities",[]):
        sw=c.get("service_worker_state")
        if sw in {"INSTALLING","ACTIVATING","WAITING"}: states["OFFLINE"]="PARTIAL"
        elif sw=="ACTIVE" and c.get("cache_version")==c.get("expected_cache_version") and c.get("offline_data_class") not in {"FORBIDDEN",None,""}: states["OFFLINE"]="READY"
        else: states["OFFLINE"]="FAIL"
    if "PUSH" in c.get("required_capabilities",[]):
        states["PUSH"]="READY" if (c.get("push_api_available") is True and c.get("push_permission_state")=="GRANTED" and c.get("push_subscription_state")=="ACTIVE") else "FAIL"
    if "CAMERA" in c.get("required_capabilities",[]):
        states["CAMERA"]="READY" if (c.get("camera_api_available") is True and c.get("camera_permission_state")=="GRANTED" and c.get("camera_device_state")=="AVAILABLE") else "FAIL"
    return states

def decide(c):
    decisive=[c.get("platform_family"),c.get("user_agent_context"),c.get("install_surface"),c.get("offline_data_class"),c.get("evidence_ref"),c.get("evidence_freshness")]
    if any(x in MISSING for x in decisive): return "HOLD"
    if c.get("evidence_freshness") in {"STALE","DISPUTED","UNKNOWN"}: return "HOLD"
    states=_cap_states(c)
    if states and all(v=="READY" for v in states.values()): return "READY"
    if any(v=="PARTIAL" for v in states.values()) and not any(v=="FAIL" for v in states.values()): return "PARTIAL"
    if any(v=="PARTIAL" for v in states.values()) and c.get("fallback_quality")=="ACCEPTABLE": return "PARTIAL"
    if any(v=="FAIL" for v in states.values()):
        if c.get("fallback_quality")=="ACCEPTABLE" and c.get("fallback_path") not in {"NONE",None,""}: return "FALLBACK"
        return "UNSUPPORTED"
    return "HOLD"

def invariant_checks(c):
    got=decide(c); states=_cap_states(c)
    return [
      got in ALLOWED,
      bool(c.get("evidence_ref")) and bool(c.get("test_fixture")),
      bool(c.get("platform_family")) and bool(c.get("user_agent_context")),
      (got!="READY") or c.get("evidence_freshness")=="CURRENT",
      (got!="READY") or (states and all(v=="READY" for v in states.values())),
    ]

def check_case(c):
    got=decide(c); return got, got==c.get("expected")
