# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-refuse-to-resume-from-a-lossy-context-recovery-marker.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-refuse-to-resume-from-a-lossy-context-recovery-marker.warrant.json
# Markdown SHA-256:   6d46b63b858bd4d6c6b489dfc06a2c79050a9803bd55ad0fcc2f0be06ddaad0f
# Code AST SHA-256:   859df5341a4ec3b73e4bb7a600f3b0e853f14d453789ea7d2d7a6ece829f3cb2
# Verified Classes:   MarkerInvalid
# Defensive Guards:   3 fail-closed invariants (zero external deps)

class MarkerInvalid(RuntimeError):
    """Raised when a lossy-context recovery marker fails closure/retention/depth checks."""
    pass


def validate_marker(marker, digest, open_calls, rejected_items):
    if marker.tier_depth != digest.tier_depth:
        raise MarkerInvalid(
            f"depth mismatch: marker at L{marker.tier_depth}, "
            f"digest at L{digest.tier_depth}; re-compaction invalidated marker"
        )
    unresolved = [c for c in open_calls if c.id not in marker.resolved_ids]
    if unresolved:
        raise MarkerInvalid(f"closure violated: {len(unresolved)} open calls")
    missing = [r for r in rejected_items if r.key not in digest.dispositions]
    if missing:
        raise MarkerInvalid(
            f"negative-fact retention violated: {[m.key for m in missing]} "
            f"absent from digest dispositions"
        )
    return True


def resume(marker, digest, raw_checkpoint, open_calls, rejected_items):
    try:
        validate_marker(marker, digest, open_calls, rejected_items)
        return digest.context
    except MarkerInvalid:
        return raw_checkpoint.context  # wholesale fallback, never partial repair
