gabriel / musehub public
Open #123 Enhancement
filed by gabriel human · 58 days ago

Wire MuseHub org + quorum model onto staging (membership: gabriel, aaronrene)

0 Anchors
Blast radius
Churn 30d
0 Proposals

Wire the MuseHub Org + Quorum Model onto Staging (membership: gabriel, aaronrene)

Background

Almost none of this needs to be built. The identity/quorum architecture already exists and is fully documented in musehub/templates/musehub/pages/docs_muse_identity.html:

  • The identity domain plugin (muse/plugins/identity/) already has a type: "human"|"agent"|"org" field on IdentityRecord, a quorum: int | null threshold field, and spawns/member_of relationship edges with authorized_by signature arrays (muse/plugins/identity/records.py).
  • Every registered identity already has a dedicated {handle}/identity Muse repo — the canonical source of truth for pubkey/quorum/relationships; Postgres is a rebuildable index, not the other way around.
  • IdentityPushValidator (musehub.graph.push_validator) already enforces I1 (acyclicity, hard error), I2 (root distance, warning), and I3 (authorization/ quorum signatures, hard error) at push time, with the exact bootstrap rule (min(quorum, prior_members) signatures required per new member) and recursive sub-org voting via QuorumEngine.effective_weight() (musehub.graph.quorum).
  • governance.json committed to a repo's HEAD already drives quorum enforcement on proposal merges — check_quorum() (musehub/services/musehub_governance.py) is already called from the proposal-merge route (musehub/api/routes/musehub/proposals.py:546-549), resolving handle-based quorum members against each member's identity repo HEAD so key rotation propagates automatically.
  • POST /api/orgs (create org identity + repo, MSign), plus member add/list/ remove, already exist server-side (musehub/api/routes/api/orgs.py).

What's actually missing is the wiring, not the architecture:

  1. No muse hub org CLI command group exists yet — org creation and membership management are only reachable by hand-building raw API calls, with no CLI wrapper mirroring the existing muse hub attestation pattern.
  2. No org exists on staging today — every repo currently listed is owned by gabriel alone (muse hub repo list --hub https://staging.musehub.ai).
  3. No governance.json is committed to any of our actual repos — the enforcement mechanism is live and wired, but nothing has ever asked it to enforce anything.
  4. It is not yet verified whether check_quorum() permits an author to count toward their own proposal's quorum (self-approval) — this is the load- bearing question for the review policy this ticket exists to implement: gabriel, and agents gabriel is directing, self-review; anyone else (starting with aaronrene) needs a formal quorum-satisfying review from an existing org member. If self-approval is not currently permitted by check_quorum(), that is either a real gap to close or a deliberate constraint to design around — this plan does not assume either answer.

This is a wiring-and-verification project, not a new-feature build. Every phase below either uses existing, documented primitives directly, or adds the minimum CLI/operational surface needed to actually exercise them.

Goal

  • A real org exists on staging MuseHub with founding member gabriel and second member aaronrene, created and verified through the actual push/ validation path (IdentityPushValidator), not by hand-editing a database row.
  • governance.json is committed to the repos this org should govern (at minimum muse and musehub), with quorum members/threshold resolved from the org's real identity repo, not hardcoded fingerprints.
  • The self-review-vs-formal-review policy is verified end-to-end against the real merge path: a gabriel-authored proposal merges without requiring a second reviewer; an aaronrene-authored proposal is blocked until it receives a quorum-satisfying review from an existing org member.
  • A muse hub org CLI command group exists if it's genuinely missing (Phase 1 confirms this before Phase 2 assumes it).
  • The existing identity docs page is updated to reference the real, live staging org as a worked example, replacing or supplementing its currently hypothetical graph-lab/acme examples.

"Done" means: every deliverable below is checked off, every test ID is green, and a real aaronrene-authored proposal against a governed repo has actually been blocked-then-approved-then-merged on staging, not just simulated in a test fixture.

Non-Goals / Out of Scope

  • Redesigning I1/I2/I3, QuorumEngine, or the HD key-derivation scheme. All of that is settled, documented, working architecture. This plan consumes it.
  • Governing every repo in the workspace immediately. Phase 4 starts with muse and musehub — extending governance.json to every other repo/ domain is a fast, mechanical follow-up once the pattern is proven on two real repos, not a reason to widen this ticket's scope now.
  • Building a web GUI org-management page. If one doesn't already exist, it's a reasonable fast-follow (flagged in Open Questions) but not blocking for the CLI/API-level goal here.
  • Onboarding anyone beyond gabriel and aaronrene. Scoped explicitly to those two; widening membership is a future, separate action.

Design

Org creation and bootstrap

Per I3's documented bootstrap rule, the founding member of an empty org self-signs — no quorum to satisfy yet, since there are zero prior members. gabriel is the founder. aaronrene joining second, with the org's quorum threshold set to 1, requires min(1, 1) = 1 signature from the existing member set ({gabriel}) — i.e., gabriel's sign-off admits aaronrene. This is the existing, documented mechanism; no new logic is needed to model "gabriel approves who joins."

Self-review vs. formal-review policy — the actual design question

The review policy gabriel described (self-review for gabriel/gabriel-directed agents; formal quorum review for everyone else) is not naturally expressed by governance.json's quorum.threshold/members alone if check_quorum() counts the proposal's own author toward the threshold — a threshold of 1 with members: ["gabriel"] would then let anyone's proposal merge the moment gabriel is listed as a member, without requiring gabriel to actually review anyone else's work. Phase 1 must determine, by reading check_quorum()'s actual implementation and by testing it directly, whether:

(a) it already excludes the proposal author from counting toward their own quorum (in which case the existing mechanism already implements exactly the policy gabriel described — an aaronrene-authored proposal literally cannot self-satisfy quorum, and a gabriel-authored proposal is a separate question addressed below), or

(b) it does not exclude the author, in which case this plan must either (i) add that exclusion as a small, targeted fix if it's clearly a gap rather than an intentional design choice, or (ii) design the policy a different way (e.g., a separate "self-merge allowed for these handles" governance field, distinct from quorum review).

Either way, gabriel's own proposals need a distinct allowance — "self- review" for the founder isn't quorum-satisfaction, it's an explicit bypass. Whether that bypass already exists (e.g., repo owner can always merge regardless of governance) or needs to be added is also a Phase 1 finding, not an assumption baked into this plan up front.

Governance rollout

governance.json is committed to a repo's main branch HEAD — an ordinary file, versioned like any other, resolved by load_governance() at merge time. Rolling it out to muse and musehub is a real commit to each repo, not a database configuration action — consistent with the workspace's existing "everything is a versioned artifact" ethos.


Phases

Each phase is fully green before the next begins. Test IDs use the ORG_NN prefix.

Phase 1 — Audit current behavior (no new code, tests only)

Before building anything, pin down exactly how the existing mechanisms behave today, with tests that exercise the real code paths (not just re-reading source).

  • ORG_01 — Confirm whether a muse hub org CLI command group exists; if not, this becomes Phase 2's deliverable list, not a re-derivation later.
  • ORG_02 — Integration test: does check_quorum() count the proposal author toward their own proposal's quorum? Exercise the real function against a constructed governance config and review set — don't infer from reading alone.
  • ORG_03 — Integration test: does the existing proposal-merge route allow a repo owner to merge their own proposal regardless of governance.json, or does governance apply uniformly to every author including the owner?
  • ORG_04 — Confirm POST /api/orgs and the member add/list/remove endpoints work end-to-end against staging with a throwaway test org (not the real gabriel/aaronrene org yet) — verifying the documented behavior is actually live on staging, not just implemented in a branch that hasn't shipped.

Phase 2 — muse hub org CLI (only if Phase 1 confirms it's missing)

  • ORG_10muse hub org create --name <name> --json, wrapping POST /api/orgs, mirroring the existing muse hub attestation create pattern (client-side validation before network I/O, standard envelope JSON output).
  • ORG_11muse hub org member add/list/remove, wrapping the corresponding /api/orgs/{org}/members endpoints.
  • ORG_12 — CLI tests mocking the API layer (same pattern as tests/test_mist_read_api_path.py's _hub_api mocking) confirming correct path construction and argument handling, not just a happy-path smoke test.

Phase 3 — Create the real org on staging

  • ORG_20 — Create the actual org (handle TBD — see Open Questions) on staging with gabriel as founding member, verified via IdentityPushValidator's real bootstrap path (self-sign, zero prior members) — not a direct database insert.
  • ORG_21 — Add aaronrene as the second member, verified through the real min(quorum, prior) signature-count path — confirm the push is rejected if gabriel's signature is missing, and succeeds when present, as a direct regression test against staging (or a staging-equivalent fixture environment if hitting real staging destructively is undesirable — see Risks).
  • ORG_22 — Confirm the org's identity repo ({org-handle}/identity) exists and its identities//relationships/ files match what §"Org creation and bootstrap" describes, read directly via muse -C {org-handle}/identity log --json and muse cat.

Phase 4 — Governance rollout on muse and musehub

  • ORG_30 — Commit governance.json to muse's main branch with quorum members resolved from the new org (handle-based, per the documented preferred form — never raw fingerprints, since handles track key rotation automatically).
  • ORG_31 — Same for musehub.
  • ORG_32 — End-to-end regression: open a real (or realistic staging- fixture) proposal authored by aaronrene against a governed repo; confirm merge is blocked until a quorum-satisfying review lands; confirm it succeeds once that review is submitted.
  • ORG_33 — End-to-end regression: open a proposal authored by gabriel (or an agent gabriel is directing) against the same governed repo; confirm the self-review bypass identified/built in Phase 1 behaves as intended — merge proceeds without requiring a second, independent reviewer.

Phase 5 — Docs and workspace policy

  • ORG_40 — Update docs_muse_identity.html's quorum section to reference the real, live staging org as a concrete worked example alongside (or replacing) the current hypothetical graph-lab/acme examples.
  • ORG_41 — Update the workspace's shared .muse/agent.md (or wherever the review-policy convention should live) to state explicitly: proposals authored by gabriel or an agent gabriel is directing may self-review; every other author's proposal requires a quorum-satisfying review from an existing governing-org member before merge.

Acceptance Criteria

  • A real org exists on staging with gabriel and aaronrene as verified members, created through the actual identity-push validation path.
  • governance.json is live on muse and musehub's main branches.
  • A real (or staging-fixture) aaronrene-authored proposal against a governed repo cannot merge without a quorum-satisfying review, and can merge once one is submitted.
  • A real (or staging-fixture) gabriel-authored proposal against the same governed repo merges without requiring a second reviewer.
  • muse hub org CLI commands exist and are tested, unless Phase 1 finds they're unnecessary because equivalent functionality already exists somewhere else in the CLI (in which case that finding replaces this criterion, not silently satisfies it).
  • No test in the suite depends on a specific staging database row surviving between runs — fixtures create and tear down their own throwaway org state where Phase 1's audit tests need real staging interaction.

Risks

  • Testing against real staging risk: several phases above call for verifying behavior against actual staging state (a real org, real proposals). Mitigation: prefer a disposable, clearly-named throwaway org/ repo for verification passes (Phase 1's ORG_04) before creating the real gabriel+aaronrene org in Phase 3, so early mistakes don't have to be unwound on the record that matters.
  • Self-review-bypass ambiguity risk: this plan explicitly does not assume how gabriel's self-review bypass works today (owner-always-merges? author-counts-toward-own-quorum? something else?) — Phase 1's findings could change Phase 4's exact implementation. That's intentional: guessing here and discovering the guess was wrong after governance.json is live on real repos is a worse failure mode than spending Phase 1 to find out first.
  • Documentation drift risk: docs_muse_identity.html is detailed and currently accurate to the underlying code per this plan's own research — Phase 5 must update it to reflect the real org, not let the doc silently become the one part of this effort that stays hypothetical.

Open Questions

  • What should the org's handle actually be? (musehub-core, muse-org, something else?) Needs a decision before Phase 3, not left implicit.
  • Should the quorum threshold be 1 (any single existing member's approval suffices) or higher, now that membership is just gabriel and aaronrene? With two members and threshold=1, aaronrene's own review would already satisfy quorum for someone else's proposal once she's a member — worth deciding deliberately whether that's the intended posture at this membership size, versus reserving quorum>1 for whenever a third member joins.
  • Does a web-GUI org-management page already exist (the earlier open musehub issues list mentioned profile/social/release-page work but nothing explicitly for org management) — if genuinely absent, should it be filed as its own follow-up issue now, or deferred until the CLI/API path above is proven?
  • Once Phase 1 answers the self-review-bypass question, does the answer belong in governance.json's schema itself (e.g. an explicit self_merge_allowed: ["gabriel"] field) or in a separate mechanism entirely? This plan intentionally leaves the exact shape open until Phase 1's findings are in.

Implementation Order

Phase 1 → Phase 2 (conditional) → Phase 3 → Phase 4 → Phase 5. Phase 1 is strictly load-bearing for every later phase — Phase 4's governance rollout depends entirely on knowing how self-review actually behaves, which is exactly what Phase 1 exists to determine before any real repo is governed.


Plan-only issue. Each phase's deliverables should be checked off in place as they land — this is operational/wiring work on existing architecture, not a new domain requiring further decomposition into separate staging issues.

Activity
gabriel opened this issue 58 days ago
No activity yet. Use the CLI to comment.