# `IdentityGraphService`/`QuorumEngine` claim to be "the unified surface enforcing all three invariants atomically" but are called from nowhere ## Background Surfaced while investigating why `muse/plugins/identity/plugin.py`'s local `merge()` only enforces I1 (acyclicity), not I2 (root distance) or I3 (quorum soundness) — see companion issues #225 and #226 for those two. While tracing where I2/I3 *are* supposed to be enforced (hub-side, since they require whole-graph state a local two-branch merge can't see), this turned up a structural gap independent of that question. ## What exists `musehub/graph/service.py::IdentityGraphService` — module docstring: "unified surface enforcing all three invariants atomically." It wraps: - `IdentityDAG` + `CycleDetector` (I1) - `RootDistanceIndex` (I2, via `root_distance()`/`human_ancestors()`) - `QuorumEngine` (I3, via `is_quorum_met()`) `musehub/graph/quorum.py::QuorumEngine` — a real, tested (see `test_graph_quorum.py`, `test_quorum_enforcement.py`) implementation of recursive weighted-vote quorum tallying: an org's vote in a parent org counts only if the org's own quorum is independently satisfied. ## The gap ```bash grep -rln "is_quorum_met\|QuorumEngine\|IdentityGraphService(" musehub/ --include="*.py" # → only musehub/graph/quorum.py and musehub/graph/service.py themselves ``` Neither class is instantiated or called from any API route, service, or the actual push-time gate (`musehub/graph/push_validator.py`, which is genuinely wired into `wire_push`). `push_validator.py` reimplements I1 from scratch with its own separate `CycleDetector` usage, computes I2 as a standalone warning using its own `RootDistanceIndex.build(dag)` call, and implements a *different, simpler* notion of "I3" inline (signature authorization per edge — see issue #226) that never touches `QuorumEngine` at all. So `IdentityGraphService` — despite its docstring's claim — is not "the" enforcement surface for anything. It's fully-built, tested, unused infrastructure sitting next to the code that actually runs. ## Why this matters - Anyone reading `service.py`'s docstring reasonably concludes this is where enforcement happens. It isn't. That's a real trap for the next person (human or agent) who needs to touch identity-graph validation and reaches for what the docstring says is authoritative. - Two implementations of overlapping logic (I1 cycle detection exists in both `service.py`'s `IdentityDAG`/`CycleDetector` path and `push_validator.py`'s separate `IdentityDAG`/`CycleDetector` usage) can drift independently. They happen to use the same underlying `dag.py` primitives today, but nothing guarantees that stays true. - `QuorumEngine`'s recursive org-voting logic represents real, tested design work that currently produces zero effect on any real push, merge, or API response. ## Open question before deciding the fix Is `QuorumEngine` dead code to delete, or the correct implementation for a **planned but not-yet-wired** governance feature (e.g., an org casting a weighted vote inside a parent org, distinct from the simpler join-authorization check `push_validator.py` already does)? Check: - Git/muse history for `quorum.py` and `service.py` — were they written as part of a larger governance feature that got partially shipped? - Any product/design doc referencing "org votes inside org" as a planned capability distinct from what `push_validator.py`'s I3 already covers. - `musehub/services/musehub_governance.py::check_quorum` (repo proposal-approval quorum — see issue #226) for any hint it was meant to eventually delegate to `QuorumEngine` for cross-org cases. ## Scope 1. Answer the open question above. 2. If dead code: delete `IdentityGraphService` and `QuorumEngine` (and their dedicated test files) entirely — per this workspace's "no legacy, delete on sight" convention — rather than leaving them as an attractive nuisance. 3. If a real planned feature: wire it into an actual call path (which one — push validation? a separate governance-vote endpoint?) and fix the docstring to stop claiming it's already "the unified surface." 4. Either way, fix `service.py`'s docstring — it currently asserts something false about the current system. ## Acceptance criteria - `IdentityGraphService`/`QuorumEngine` either have at least one real caller outside their own module/tests, or are removed. - No docstring in the codebase claims enforcement that isn't actually wired up.