gabriel / musehub public
issue-227-i3-naming-collision-three-quorum-concepts.md markdown
93 lines 4.3 KB
Raw
sha256:7281683f5c41e5d88b6d8811fbdafebd3e01a0c9dcd90975cfcb444ba71e8e81 docs: add local source-of-truth for musehub#225, #226, #227… Sonnet 5 23 hours ago

"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.

# 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.

# 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.
File History 1 commit
sha256:7281683f5c41e5d88b6d8811fbdafebd3e01a0c9dcd90975cfcb444ba71e8e81 docs: add local source-of-truth for musehub#225, #226, #227… Sonnet 5 23 hours ago