"""TDD — I3: Quorum soundness invariant. An org's vote in a parent org counts only if that org's own quorum is independently satisfied. Recursive. Terminates because I1 guarantees the graph is a DAG. """ from __future__ import annotations from collections.abc import Mapping from decimal import Decimal import pytest from musehub.graph.dag import EdgeType, GraphEdge, IdentityDAG, NodeType from musehub.graph.quorum import OrgSpec, QuorumEngine, VoteRecord S = EdgeType.SPAWNS M = EdgeType.MEMBER_OF def spec(handle: str, quorum: int, members: Mapping[str, Decimal]) -> OrgSpec: """Convenience constructor for OrgSpec.""" return OrgSpec(handle=handle, quorum=quorum, member_weights=members) def vote(voter: str, org: str) -> VoteRecord: return VoteRecord(voter_handle=voter, org_handle=org) # ── Simple flat orgs ────────────────────────────────────────────────────────── class TestFlatQuorum: def test_quorum_met_exact_threshold(self) -> None: # 3 members, quorum=2, exactly 2 vote engine = QuorumEngine( orgs={"acme": spec("acme", quorum=2, members={ "alice": Decimal("1"), "bob": Decimal("1"), "carol": Decimal("1"), })} ) votes = [vote("alice", "acme"), vote("bob", "acme")] assert engine.is_quorum_met("acme", votes) is True def test_quorum_not_met_one_short(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=2, members={ "alice": Decimal("1"), "bob": Decimal("1"), "carol": Decimal("1"), })} ) votes = [vote("alice", "acme")] assert engine.is_quorum_met("acme", votes) is False def test_quorum_not_met_no_votes(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=1, members={"alice": Decimal("1")})} ) assert engine.is_quorum_met("acme", []) is False def test_quorum_1_met_by_single_vote(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=1, members={"alice": Decimal("1")})} ) assert engine.is_quorum_met("acme", [vote("alice", "acme")]) is True def test_unanimous_quorum(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=3, members={ "alice": Decimal("1"), "bob": Decimal("1"), "carol": Decimal("1"), })} ) votes = [vote("alice", "acme"), vote("bob", "acme"), vote("carol", "acme")] assert engine.is_quorum_met("acme", votes) is True def test_non_member_vote_does_not_count(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=1, members={"alice": Decimal("1")})} ) # dave is not a member of acme assert engine.is_quorum_met("acme", [vote("dave", "acme")]) is False # ── Weighted members ────────────────────────────────────────────────────────── class TestWeightedQuorum: def test_weighted_vote_reaches_quorum(self) -> None: # alice has weight 2, quorum=2 → alice alone satisfies it engine = QuorumEngine( orgs={"acme": spec("acme", quorum=2, members={ "alice": Decimal("2"), "bob": Decimal("1"), })} ) assert engine.is_quorum_met("acme", [vote("alice", "acme")]) is True def test_low_weight_vote_does_not_reach_quorum(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=3, members={ "alice": Decimal("1"), "bob": Decimal("1"), "carol": Decimal("1"), })} ) # only alice (weight 1) voted — needs 3 assert engine.is_quorum_met("acme", [vote("alice", "acme")]) is False def test_fractional_weights_sum_to_quorum(self) -> None: engine = QuorumEngine( orgs={"acme": spec("acme", quorum=1, members={ "alice": Decimal("0.5"), "bob": Decimal("0.5"), })} ) votes = [vote("alice", "acme"), vote("bob", "acme")] assert engine.is_quorum_met("acme", votes) is True # ── Nested orgs — quorum propagation ───────────────────────────────────────── class TestNestedQuorum: def _two_level_engine(self) -> QuorumEngine: # parent-org has [alice, sub-org] as members, quorum=2 # sub-org has [bob, carol] as members, quorum=1 return QuorumEngine(orgs={ "parent-org": spec("parent-org", quorum=2, members={ "alice": Decimal("1"), "sub-org": Decimal("1"), }), "sub-org": spec("sub-org", quorum=1, members={ "bob": Decimal("1"), "carol": Decimal("1"), }), }) def test_org_vote_counts_when_its_quorum_met(self) -> None: engine = self._two_level_engine() # alice votes in parent; bob votes in sub-org (satisfying sub-org quorum=1) # sub-org's vote in parent then counts → parent total = 2 → met votes = [ vote("alice", "parent-org"), vote("bob", "sub-org"), vote("sub-org", "parent-org"), ] assert engine.is_quorum_met("parent-org", votes) is True def test_org_vote_does_not_count_when_its_quorum_not_met(self) -> None: engine = self._two_level_engine() # sub-org votes in parent, but nobody voted inside sub-org → sub-org quorum not met votes = [ vote("alice", "parent-org"), vote("sub-org", "parent-org"), ] assert engine.is_quorum_met("parent-org", votes) is False def test_parent_quorum_not_met_even_if_sub_quorum_met(self) -> None: engine = self._two_level_engine() # sub-org quorum met (bob voted) but only sub-org votes in parent → total=1 < quorum=2 votes = [ vote("bob", "sub-org"), vote("sub-org", "parent-org"), ] assert engine.is_quorum_met("parent-org", votes) is False def test_three_level_nesting_all_quorums_met(self) -> None: engine = QuorumEngine(orgs={ "top": spec("top", quorum=2, members={"alice": Decimal("1"), "mid": Decimal("1")}), "mid": spec("mid", quorum=1, members={"bob": Decimal("1"), "bot": Decimal("1")}), "bot": spec("bot", quorum=1, members={"carol": Decimal("1")}), }) # carol votes in bot → bot quorum met # bot votes in mid → mid quorum met # alice + mid vote in top → top quorum met votes = [ vote("carol", "bot"), vote("bot", "mid"), vote("bob", "mid"), # extra, doesn't hurt vote("mid", "top"), vote("alice", "top"), ] assert engine.is_quorum_met("top", votes) is True def test_three_level_nesting_middle_quorum_not_met(self) -> None: engine = QuorumEngine(orgs={ "top": spec("top", quorum=2, members={"alice": Decimal("1"), "mid": Decimal("1")}), "mid": spec("mid", quorum=2, members={"bob": Decimal("1"), "carol": Decimal("1")}), }) # only bob voted in mid → mid quorum (needs 2) not met → mid vote in top doesn't count votes = [ vote("bob", "mid"), vote("mid", "top"), vote("alice", "top"), ] assert engine.is_quorum_met("top", votes) is False # ── Effective weight ────────────────────────────────────────────────────────── class TestEffectiveWeight: def test_human_effective_weight_is_direct(self) -> None: engine = QuorumEngine(orgs={ "acme": spec("acme", quorum=1, members={"alice": Decimal("2")}) }) assert engine.effective_weight("acme", "alice", []) == Decimal("2") def test_org_effective_weight_zero_when_quorum_not_met(self) -> None: engine = QuorumEngine(orgs={ "parent": spec("parent", quorum=1, members={"sub": Decimal("3")}), "sub": spec("sub", quorum=1, members={"alice": Decimal("1")}), }) # sub's quorum not met (alice hasn't voted in sub) → sub weight in parent = 0 assert engine.effective_weight("parent", "sub", []) == Decimal("0") def test_org_effective_weight_is_direct_when_quorum_met(self) -> None: engine = QuorumEngine(orgs={ "parent": spec("parent", quorum=1, members={"sub": Decimal("3")}), "sub": spec("sub", quorum=1, members={"alice": Decimal("1")}), }) votes = [vote("alice", "sub"), vote("sub", "parent")] assert engine.effective_weight("parent", "sub", votes) == Decimal("3") # ── Unknown org ─────────────────────────────────────────────────────────────── class TestUnknownOrg: def test_unknown_org_raises(self) -> None: engine = QuorumEngine(orgs={}) with pytest.raises(KeyError): engine.is_quorum_met("ghost-org", [])