# "Quorum" names three unrelated concepts across the codebase, and identity's own "I3" has two non-reconciled definitions ## Background Companion to #225 (dead-code cleanup) and #226 (I2 hard-error question), surfaced during the same identity-domain invariant investigation. ## The collision, concretely **Definition A — `musehub/graph/push_validator.py`'s "I3" (actually enforced, hard error):** Per-edge signature authorization. Does the right party's Ed25519 signature appear in `authorized_by` for a `spawns`/`member_of` edge, with a bootstrap exception for an org's founding member and a `min(quorum, prior_members)` signature-count rule for subsequent joins. This is real, wired into `wire_push`, and actually rejects bad pushes. ```python # push_validator.py module docstring I3 Authorization — hard error (push rejected) ``` **Definition B — `musehub/graph/quorum.py`'s "I3" (real, tested, never called):** Recursive weighted-vote tallying. An org's vote inside a *parent* org counts only if that org's own quorum is independently satisfied, terminating because I1 guarantees no circular org membership. ```python # quorum.py module docstring """I3 — Quorum soundness invariant. An org's vote in a parent org counts only if that org's own quorum is independently satisfied. Recursive.""" ``` `QuorumEngine` from this file is never invoked by `push_validator.py`, or by anything else outside its own module/tests (see #225). **Definition C — `musehub/services/musehub_governance.py::check_quorum` (unrelated domain entirely):** Counts approved code-review approvals against a repo's proposal governance config (`governance["quorum"]["threshold"]`/`["members"]`) to decide whether a proposal has enough sign-off to merge. Nothing to do with the identity graph, org membership, or `spawns`/`member_of` edges — this is repo/proposal governance, a completely different subsystem that happens to reuse the word "quorum." ## Why this matters - Two different pieces of code both claim to be "I3" for the identity domain and describe genuinely different mechanisms (signature-count authorization vs. recursive vote-weight tallying). Anyone implementing a third caller, or auditing "is I3 satisfied," has to know which of the two definitions is meant — the name alone doesn't disambiguate. - A third, entirely unrelated "quorum" (proposal-review approval count) shares no code, no data model, and no invariant number with the other two, but shares the English word — searching the codebase for "quorum" surfaces all three undifferentiated. - This is exactly the kind of naming collision that produces a confidently-wrong fix later: someone "fixing quorum enforcement" could plausibly patch the wrong one of the three without realizing three exist. ## Scope 1. Decide canonical terminology. Suggestion (not a mandate — a product/naming call): keep "I3" reserved for whichever of A/B is actually the identity domain's intended invariant (likely A, since it's the one actually enforced), rename B to something distinct (e.g. "org vote quorum" or "recursive governance quorum") if it's kept at all per #225's dead-code decision, and leave C's "proposal review quorum" as its own clearly-scoped term with no shared number. 2. Update both `push_validator.py`'s and `quorum.py`'s module docstrings (and `muse/plugins/identity/plugin.py`'s "I3 Quorum soundness" line) to match the resolved terminology — right now the plugin's own docstring uses the label "Quorum soundness," which reads as pointing at Definition B (the thing nothing calls), not Definition A (the thing that's actually enforced at push time), which is itself confusing independent of the dead-code question. 3. Cross-reference #225's resolution — if `QuorumEngine`/`quorum.py` gets deleted as dead code, this issue mostly resolves by removing Definition B entirely, leaving only A and C (which don't collide once B is gone, since they were never actually confused with each other, only both with the "I3" label). ## Acceptance criteria - No two pieces of enforced-or-intended-to-be-enforced logic in this codebase share the name "I3" (or "quorum" more broadly) while meaning different things. - `muse/plugins/identity/plugin.py`'s docstring accurately names whichever mechanism is real.