# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/which-invariants-prevent-false-forget-verification-in-read-write-forget-memory-tool-schemas.md
# Remnant Warrant:    https://corpusfetch.com/c/which-invariants-prevent-false-forget-verification-in-read-write-forget-memory-tool-schemas.warrant.json
# Markdown SHA-256:   b8f1b5f9bc92bd65103b06f552f5dc4df80d22dc1ec1e1f614846779fef843e2
# Code AST SHA-256:   26253fbb3580b4b77204e22ce0a181fddc48bd105b9a5e6043725c248f7bc905
# Verified Classes:   ForgetVerificationError
# Defensive Guards:   3 fail-closed invariants (zero external deps)

class ForgetVerificationError(RuntimeError):
    """Raised when a forget cannot be confirmed by a valid read-after-forget oracle."""
    pass


ABSENCE_SENTINEL = object()  # distinct from "", None, [], etc.


def verify_forget(memory_client, key, forget_path, *, durability_barrier=True):
    """
    Verify a forget only if the read traverses the same consistency domain
    and the schema yields a distinct absence sentinel.

    Returns True only on a valid, positive verification.
    Raises ForgetVerificationError otherwise -- never returns a false positive.
    """
    if not durability_barrier:
        raise ForgetVerificationError(
            f"refusing to verify forget of {key!r}: durability barrier not crossed; "
            "read may observe pre-delete state on a replica"
        )

    result = memory_client.read(key, path=forget_path, sentinel=ABSENCE_SENTINEL)

    if result is ABSENCE_SENTINEL:
        return True  # valid oracle: distinct absence on identical path

    if result in ("", None, [], {}):
        # Zero value is NOT evidence of erasure -- schema cannot distinguish
        # "forgotten" from "legitimately empty".
        raise ForgetVerificationError(
            f"forget of {key!r} unverified: read returned empty value, not an "
            "absence sentinel; schema cannot distinguish erased from empty"
        )

    raise ForgetVerificationError(
        f"forget of {key!r} failed verification: value still present at {forget_path!r}"
    )


def forget_and_verify(memory_client, key, *, aliases=(), case_variants=()):
    paths = [key, *aliases, *case_variants]
    for p in paths:
        memory_client.forget(p)
    memory_client.flush_durability()  # cross the barrier before verifying
    for p in paths:
        verify_forget(memory_client, key, forget_path=p, durability_barrier=True)
    return True
