Module adcp.reporting.revision_selection
Strict, pure publication selection shared by seller and buyer projections.
Validate the whole obligation history before choosing finality. Destination state, timestamps and readability never choose a publication. In particular, an official close does not supersede (or excuse damage in) the snapshot chain.
Functions
def select_reporting_revision(revisions: Sequence[R],
*,
account_id: str,
reporting_obligation_id: str,
required_finality: str) ‑> ReportingRevisionSelected[~R] | ReportingRevisionNotReady | ReportingRevisionCorrupt-
Expand source code
def select_reporting_revision( revisions: Sequence[R], *, account_id: str, reporting_obligation_id: str, required_finality: str, ) -> ReportingRevisionSelection[R]: """Linear-time, order-independent selection, including disconnected cycles. Only empty history or a missing required official is ordinary not-ready. The caller supplies every retained revision belonging to the obligation, without filtering by finality, readability, or existing materializations. A selected unreadable revision remains selected: repair it, never fall back. """ if ( type(account_id) is not str or type(reporting_obligation_id) is not str or any( type(r.account_id) is not str or type(r.reporting_obligation_id) is not str or r.account_id != account_id or r.reporting_obligation_id != reporting_obligation_id for r in revisions ) ): return ReportingRevisionCorrupt("ownership_mismatch") if any( type(r.reporting_revision_id) is not str or not r.reporting_revision_id or ( r.supersedes_reporting_revision_id is not None and type(r.supersedes_reporting_revision_id) is not str ) for r in revisions ): return ReportingRevisionCorrupt("invalid_revision_identity") by_id = {r.reporting_revision_id: r for r in revisions} if len(by_id) != len(revisions): return ReportingRevisionCorrupt("duplicate_revision_id") if ( type(required_finality) is not str or required_finality not in {"snapshot", "official"} or any( type(r.finality) is not str or r.finality not in {"snapshot", "official"} for r in revisions ) ): return ReportingRevisionCorrupt("invalid_finality") if any( r.supersedes_reporting_revision_id is not None and r.supersedes_reporting_revision_id not in by_id for r in revisions ): return ReportingRevisionCorrupt("missing_predecessor") if any( r.supersedes_reporting_revision_id is not None and by_id[r.supersedes_reporting_revision_id].finality != r.finality for r in revisions ): return ReportingRevisionCorrupt("cross_finality_edge") if any( r.finality == "official" and r.supersedes_reporting_revision_id is not None for r in revisions ): return ReportingRevisionCorrupt("official_predecessor") officials = [r for r in revisions if r.finality == "official"] if len(officials) > 1: return ReportingRevisionCorrupt("multiple_officials") snapshots = [r for r in revisions if r.finality == "snapshot"] successors: dict[str, str] = {} for revision in snapshots: predecessor = revision.supersedes_reporting_revision_id if predecessor is not None: if predecessor in successors: return ReportingRevisionCorrupt("forked_snapshot_history") successors[predecessor] = revision.reporting_revision_id # Walk each component once. A unique-looking leaf cannot hide a cycle. visited: set[str] = set() for revision in snapshots: path: set[str] = set() node: str | None = revision.reporting_revision_id while node is not None and node not in visited: if node in path: return ReportingRevisionCorrupt("revision_cycle") path.add(node) node = by_id[node].supersedes_reporting_revision_id visited.update(path) roots = [r for r in snapshots if r.supersedes_reporting_revision_id is None] if snapshots and len(roots) != 1: return ReportingRevisionCorrupt("disconnected_snapshot_history") if not revisions: return ReportingRevisionNotReady("empty_history") if officials: return ReportingRevisionSelected(officials[0]) if required_finality == "official": return ReportingRevisionNotReady("official_required") leaf = next(r for r in snapshots if r.reporting_revision_id not in successors) return ReportingRevisionSelected(leaf)Linear-time, order-independent selection, including disconnected cycles.
Only empty history or a missing required official is ordinary not-ready. The caller supplies every retained revision belonging to the obligation, without filtering by finality, readability, or existing materializations. A selected unreadable revision remains selected: repair it, never fall back.
Classes
class ReportingRevisionCorrupt (reason: "Literal['ownership_mismatch', 'duplicate_revision_id', 'invalid_revision_identity', 'invalid_finality', 'missing_predecessor', 'cross_finality_edge', 'official_predecessor', 'forked_snapshot_history', 'disconnected_snapshot_history', 'revision_cycle', 'multiple_officials']")-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionCorrupt: # Closed diagnostics: no row data, credentials or provider errors. reason: Literal[ "ownership_mismatch", "duplicate_revision_id", "invalid_revision_identity", "invalid_finality", "missing_predecessor", "cross_finality_edge", "official_predecessor", "forked_snapshot_history", "disconnected_snapshot_history", "revision_cycle", "multiple_officials", ] kind: Literal["corrupt"] = field(default="corrupt", init=False)ReportingRevisionCorrupt(reason: "Literal['ownership_mismatch', 'duplicate_revision_id', 'invalid_revision_identity', 'invalid_finality', 'missing_predecessor', 'cross_finality_edge', 'official_predecessor', 'forked_snapshot_history', 'disconnected_snapshot_history', 'revision_cycle', 'multiple_officials']")
Instance variables
var kind : Literal['corrupt']-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionCorrupt: # Closed diagnostics: no row data, credentials or provider errors. reason: Literal[ "ownership_mismatch", "duplicate_revision_id", "invalid_revision_identity", "invalid_finality", "missing_predecessor", "cross_finality_edge", "official_predecessor", "forked_snapshot_history", "disconnected_snapshot_history", "revision_cycle", "multiple_officials", ] kind: Literal["corrupt"] = field(default="corrupt", init=False) var reason : Literal['ownership_mismatch', 'duplicate_revision_id', 'invalid_revision_identity', 'invalid_finality', 'missing_predecessor', 'cross_finality_edge', 'official_predecessor', 'forked_snapshot_history', 'disconnected_snapshot_history', 'revision_cycle', 'multiple_officials']-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionCorrupt: # Closed diagnostics: no row data, credentials or provider errors. reason: Literal[ "ownership_mismatch", "duplicate_revision_id", "invalid_revision_identity", "invalid_finality", "missing_predecessor", "cross_finality_edge", "official_predecessor", "forked_snapshot_history", "disconnected_snapshot_history", "revision_cycle", "multiple_officials", ] kind: Literal["corrupt"] = field(default="corrupt", init=False)
class ReportingRevisionNotReady (reason: "Literal['empty_history', 'official_required']")-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionNotReady: reason: Literal["empty_history", "official_required"] kind: Literal["not_ready"] = field(default="not_ready", init=False)ReportingRevisionNotReady(reason: "Literal['empty_history', 'official_required']")
Instance variables
var kind : Literal['not_ready']-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionNotReady: reason: Literal["empty_history", "official_required"] kind: Literal["not_ready"] = field(default="not_ready", init=False) var reason : Literal['empty_history', 'official_required']-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionNotReady: reason: Literal["empty_history", "official_required"] kind: Literal["not_ready"] = field(default="not_ready", init=False)
class ReportingRevisionSelected (revision: R)-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionSelected(Generic[R]): revision: R kind: Literal["selected"] = field(default="selected", init=False)ReportingRevisionSelected(revision: 'R')
Ancestors
- typing.Generic
Instance variables
var kind : Literal['selected']-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionSelected(Generic[R]): revision: R kind: Literal["selected"] = field(default="selected", init=False) var revision : ~R-
Expand source code
@dataclass(frozen=True, slots=True) class ReportingRevisionSelected(Generic[R]): revision: R kind: Literal["selected"] = field(default="selected", init=False)
class RevisionHistoryEntry (account_id: str,
reporting_obligation_id: str,
reporting_revision_id: str,
finality: str,
supersedes_reporting_revision_id: str | None = None)-
Expand source code
@dataclass(frozen=True, slots=True) class RevisionHistoryEntry: """Adapter for wire revisions whose ownership is established by their caller.""" account_id: str reporting_obligation_id: str reporting_revision_id: str finality: str supersedes_reporting_revision_id: str | None = NoneAdapter for wire revisions whose ownership is established by their caller.
Instance variables
var account_id : str-
Expand source code
@dataclass(frozen=True, slots=True) class RevisionHistoryEntry: """Adapter for wire revisions whose ownership is established by their caller.""" account_id: str reporting_obligation_id: str reporting_revision_id: str finality: str supersedes_reporting_revision_id: str | None = None var finality : str-
Expand source code
@dataclass(frozen=True, slots=True) class RevisionHistoryEntry: """Adapter for wire revisions whose ownership is established by their caller.""" account_id: str reporting_obligation_id: str reporting_revision_id: str finality: str supersedes_reporting_revision_id: str | None = None var reporting_obligation_id : str-
Expand source code
@dataclass(frozen=True, slots=True) class RevisionHistoryEntry: """Adapter for wire revisions whose ownership is established by their caller.""" account_id: str reporting_obligation_id: str reporting_revision_id: str finality: str supersedes_reporting_revision_id: str | None = None var reporting_revision_id : str-
Expand source code
@dataclass(frozen=True, slots=True) class RevisionHistoryEntry: """Adapter for wire revisions whose ownership is established by their caller.""" account_id: str reporting_obligation_id: str reporting_revision_id: str finality: str supersedes_reporting_revision_id: str | None = None var supersedes_reporting_revision_id : str | None-
Expand source code
@dataclass(frozen=True, slots=True) class RevisionHistoryEntry: """Adapter for wire revisions whose ownership is established by their caller.""" account_id: str reporting_obligation_id: str reporting_revision_id: str finality: str supersedes_reporting_revision_id: str | None = None