LedgerConflict
An integrity fault EntitlementLedger.validate derives from merged state.
Conflicts are surfaced, never resolved by timestamp (design §4.6): every replica folds the same merged state into the same, deterministically-sorted report. The affected lineage contributes no spendable holdings (quarantine is transitive down the path), and nothing here is ever silently resolved by arrival order or a clock.
validate() is an eventually-consistent diagnostic, not a safety gate. Safety comes from the local holdings check each mutator runs on the actor's own complete state — never from a conflict report. Under partial delivery a report may transiently list a conflict that a later anti-entropy round dissolves (see EntitlementLedger); consumers must not hard-gate on validate().isEmpty() while rebalancing is in flight.
Comparable so a report is emitted in one canonical order on every peer — the ordering is derived from the typed identities below (no stringified keys).
Inheritors
Types
A Lifecycle.RETIRED edge across which entitlement nonetheless still stands — outstanding(e) != 0 (design §5.1, §10.10). EntitlementLedger.retire refuses to retire an edge until it has fully drained, so on a causally-complete state this means a late delegation crossed a generation the cluster had already retired: a replica acting on stale Lifecycle.ACTIVE state delegated down an edge another replica had already close-drained-retired. The max-register makes RETIRED dominate the merge (closure dominance); this report surfaces the late crossing rather than resolving it by arrival order, and the stranded entitlement is reconciled by the control plane.
The global supply backstop: total service charged has exceeded total supply ever minted — Σ_e effLeafSpent(e) > Σ mintedTotal (design §10.1 conservation, §10.12).
A group with two or more live inbound generations — two inbound edges that are each Lifecycle.ACTIVE or Lifecycle.CLOSING (a still-draining closing edge counts; it can still carry entitlement). This is the topology fork the design forbids resolving by last-writer-wins on a parent pointer (§5.2, §10.11). It arises when two replicas concurrently attach a different inbound edge for the same child — e.g. one activates e2 while another has e1 active or closing; the lifecycle max-register keeps both live, so every replica folds the merged state into the same report rather than silently picking a winner. The child's whole lineage is quarantined — EntitlementLedger.holdings returns zero at or below it — and no new entitlement may be delegated across either contested edge (EntitlementLedger.delegate returns null). This predicate is exactly the one EntitlementLedger quarantines on, so quarantine and report always coincide (§10.11).
A group that lies on a topology cycle — walking its live inbound edges root-ward returns to the group itself instead of reaching a root. Like DualActiveInbound this is a fork the merge deliberately retains rather than resolving by arrival order (§5.2): two replicas each attached an inbound edge, and together the records close a loop. The whole cycle is quarantined — EntitlementLedger.holdings is zero at every group on it and at every group below it — so this report is what makes that quarantine visible (§10.11: quarantine ⟺ explicit report).
An edge whose effective spend has gone negative — leafSpent + relocIn − relocOut < 0 on either the leaf or the roll-up family (issue #1693; relocation design §5.3's lower bound, §12.5).
Transfer rows the topology has moved out from under (issue #2366) — a PathKey no group's live lineage reads any more, still carrying a peer-to-peer hand-off that EntitlementLedger.holdings therefore no longer counts.
An edge whose aggregate charged-plus-returned exceeds what was ever issued down it: leafSpent(e) + rollupSpent(e) + returned(e) > issued(e). Checked sum-wise on aggregate values, never per slot — a peer may legitimately return entitlement it received by transfer, so a per-slot returned > issued is fine; only the edge total crossing issued is a fault (design §4.6).
A (group, replica) whose derived EntitlementLedger.holdings is negative — the real overspend net (design §4.6): a debit beyond a peer's pocket that nonetheless stays within the edge sum passes PerEdgeSafety yet strands holdings persistently negative. On a fully-delivered state this is a genuine overspend; under partial delivery of a multi-hop transfer-funded charge it may surface transiently and self-heal on anti-entropy.
Two distinct immutable AttachmentRecords under one AttachmentId — a topology fork the merge deliberately retained rather than resolving by last-writer-wins on a parent pointer (design §5.2). The whole lineage is quarantined: EntitlementLedger.holdings returns zero for any group at or below the divergent edge.