# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-detect-provenance-laundered-memory-writes-when-a-blackboard-enforces-per-writer-attribution-but-not-per-entry-lineage.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-detect-provenance-laundered-memory-writes-when-a-blackboard-enforces-per-writer-attribution-but-not-per-entry-lineage.warrant.json
# Markdown SHA-256:   8929d1fb44cbc742dcfaf1ed674ec1a24d5f4cc17235a93d86e0fa983bba5c97
# Code AST SHA-256:   194bc3511024922555d8fbf4ddd7a6618ed981c44bd27bdeb87c69b27f8b7d2c
# Verified Classes:   ProvenanceLaunderingError, EntryView
# Defensive Guards:   4 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from typing import Mapping, FrozenSet


class ProvenanceLaunderingError(RuntimeError):
    """Raised when a blackboard entry's trust cannot be tied to contributing writers."""


@dataclass(frozen=True)
class EntryView:
    entry_id: str
    author: str
    last_writer: str
    # field -> set of writers that have contributed to that field's current value
    contributing_writers: Mapping[str, FrozenSet[str]]
    # field -> set of writers trusted by the reading agent
    trusted_writers: FrozenSet[str]


def assert_provenance_safe(entry: EntryView, fields_consumed) -> None:
    """
    Enforce that every consumed field's contributing-writer set is fully
    enumerable and fully trusted. Reject author-pinned trust.
    """
    if not entry.contributing_writers:
        raise ProvenanceLaunderingError(
            f"entry {entry.entry_id!r} exposes no contributing-writer lineage; "
            f"author={entry.author!r} last_writer={entry.last_writer!r} is insufficient "
            f"because annotations can launder trust"
        )

    for field in fields_consumed:
        writers = entry.contributing_writers.get(field)
        if writers is None:
            raise ProvenanceLaunderingError(
                f"entry {entry.entry_id!r} has no lineage for consumed field {field!r}; "
                f"cannot enumerate contributing writers"
            )
        untrusted = writers - entry.trusted_writers
        if untrusted:
            raise ProvenanceLaunderingError(
                f"entry {entry.entry_id!r} field {field!r} was contributed by "
                f"untrusted writers {sorted(untrusted)!r}; "
                f"author={entry.author!r} does not confer trust on their content"
            )
        if entry.last_writer not in writers:
            raise ProvenanceLaunderingError(
                f"entry {entry.entry_id!r} field {field!r} claims last_writer "
                f"{entry.last_writer!r} not present in contributing set {sorted(writers)!r}; "
                f"lineage is internally inconsistent"
            )


def guarded_read(entry: EntryView, fields_consumed, side_effecting: bool):
    if side_effecting:
        assert_provenance_safe(entry, fields_consumed)
    return {f: entry.contributing_writers.get(f) for f in fields_consumed}
