```python
import json
import math
from typing import Iterable, List, Dict, Any


def summarize(lines: Iterable[str]) -> List[Dict[str, Any]]:
    """
    Summarize JSONL lines by service.
    
    Each valid line must be a JSON object with:
    - service: non-empty string
    - status: integer (not bool), 100-599
    - latency_ms: non-negative int or float (not bool)
    
    Invalid lines (empty, parse failure, non-object, invalid fields) are ignored.
    Extra fields are allowed.
    
    Returns a list sorted by service name, each item is:
    {"service": name, "count": valid count, "errors": count of status>=500, "p95_ms": p95}
    
    p95 uses nearest-rank: after sorting latencies, take the ceil(0.95*n)-th item (1-indexed).
    """
    from collections import defaultdict
    
    # Collect valid records per service
    service_data = defaultdict(lambda: {"count": 0, "errors": 0, "latencies": []})
    
    for line in lines:
        # Skip empty lines
        if not line or not line.strip():
            continue
        
        try:
            obj = json.loads(line)
        except (json.JSONDecodeError, ValueError):
            continue
        
        # Must be a dict (JSON object)
        if not isinstance(obj, dict):
            continue
        
        # Check service: non-empty string
        service = obj.get("service")
        if not isinstance(service, str) or not service:
            continue
        
        # Check status: integer, not bool, 100-599
        status = obj.get("status")
        if isinstance(status, bool):
            continue
        if not isinstance(status, int):
            continue
        if status < 100 or status > 599:
            continue
        
        # Check latency_ms: non-negative int or float, not bool
        latency_ms = obj.get("latency_ms")
        if isinstance(latency_ms, bool):
            continue
        if not isinstance(latency_ms, (int, float)):
            continue
        if latency_ms < 0:
            continue
        
        # Valid record
        entry = service_data[service]
        entry["count"] += 1
        if status >= 500:
            entry["errors"] += 1
        entry["latencies"].append(latency_ms)
    
    # Build result sorted by service name
    result = []
    for service in sorted(service_data.keys()):
        entry = service_data[service]
        n = entry["count"]
        if n == 0:
            p95 = 0.0
        else:
            latencies = sorted(entry["latencies"])
            # nearest-rank: ceil(0.95 * n), 1-indexed
            rank = math.ceil(0.95 * n)
            # rank is 1-indexed, so index is rank - 1
            p95 = latencies[rank - 1]
        
        result.append({
            "service": service,
            "count": n,
            "errors": entry["errors"],
            "p95_ms": p95
        })
    
    return result
```