Multi-Remote Workflow — Local, Staging, Production
MuseHub's own source repos (muse, musehub, agentception, and other ecosystem
repos) are pushed to three remotes, each with a distinct role. This doc defines
where issues and merge proposals (MPs) belong, and walks through the exact
command flow for the most common case — merging a change and shipping it live.
The three remotes
| Remote | URL pattern | Role |
|---|---|---|
local |
https://localhost:1337/<owner>/<repo> |
Local dev-instance mirror. Not collaborative — one operator's own MuseHub server. |
staging |
https://staging.musehub.ai/<owner>/<repo> |
The canonical internal collaboration hub. All internal issues, proposals, and merges happen here. |
production |
https://musehub.ai/<owner>/<repo> |
The public, live deployment target. Receives already-reviewed code. Also the canonical place for public issues/MPs from external contributors, and for official releases/tags. |
Where issues and MPs belong
MuseHub itself is open source. Once a repo is live on production, the public can browse it, file issues, and open merge proposals there — we don't control that, and shouldn't try to funnel external contributors through staging (they have no reason to know staging exists, and staging isn't meant to be public).
That means issues and MPs exist on two different hubs depending on who's filing them, and it's important not to confuse the two:
| Source | Hub | Why |
|---|---|---|
| Internal team (Gabriel, Aaron, future team members) | staging | Staging is the internal collaboration surface — every internal issue, proposal, and dev-branch merge happens here. This is where dev actually advances. |
| External/public contributors | production | Production is what the public sees and interacts with at musehub.ai. Their issues and MPs land there by default, since that's the only hub they have access to. |
Internal workflow rule: never create internal issues or MPs on production.
Production is a deployment target for already-reviewed work, not a place
the team uses to develop. If an external contributor opens a proposal on
production, it needs to be manually reviewed and — if accepted — the actual
change re-created as a branch off staging's dev (or cherry-picked via
muse code semantic-cherry-pick) so it goes through the same internal review
path as everything else, rather than being merged directly into production's
independent branch history.
Releases and tags — always on production
Official releases (muse release add, muse hub release create) are cut
against production, since that's the live, public environment being
shared via URL. A release should always point at something actually running
where people can see it. It's fine to mirror the same release record to
staging afterward for internal consistency, but production's release is the
one that gets linked externally.
Concrete example — bumping musehub's PATCH version
This is the full, worked example for the most common internal change: a version bump, from local edit through to a live production release.
# 1. Start from a current local dev
muse -C ~/ecosystem/musehub checkout dev
muse -C ~/ecosystem/musehub pull staging dev
# 2. Create a feature branch off dev
muse -C ~/ecosystem/musehub checkout -b bump/musehub-v0.4.2 \
--intent "Bump musehub PATCH version to 0.4.2" \
--resumable
# 3. Make the change locally (edit the version file), then commit
muse -C ~/ecosystem/musehub code add <version-file>
muse -C ~/ecosystem/musehub commit -m "chore: bump musehub to v0.4.2" \
--agent-id claude-code --model-id claude-sonnet-5 --sign
# 4. Push the feature branch to staging — NOT production.
# Staging is where the MP and review happen.
muse -C ~/ecosystem/musehub push staging bump/musehub-v0.4.2
# 5. Open the proposal against staging's dev
muse -C ~/ecosystem/musehub hub proposal create \
--hub https://staging.musehub.ai \
--title "chore: bump musehub to v0.4.2" \
--from-branch bump/musehub-v0.4.2 \
--to-branch dev
# 6. Merge the proposal — this is where the actual merge into dev happens
muse -C ~/ecosystem/musehub hub proposal merge <proposal-id> \
--hub https://staging.musehub.ai
# 7. Sync local dev with what just got merged on staging
muse -C ~/ecosystem/musehub checkout dev
muse -C ~/ecosystem/musehub pull staging dev
# 8. Keep localhost's own dev mirror current too
muse -C ~/ecosystem/musehub push local dev
# 9. Publish the reviewed state to production — a straight push, no MP.
# It already went through review on staging; production doesn't
# re-review internal changes.
muse -C ~/ecosystem/musehub push production dev
# 10. When ready to actually cut a release, promote dev -> main.
# This is a deliberate, infrequent act — a direct merge, not a proposal.
muse -C ~/ecosystem/musehub checkout main
muse -C ~/ecosystem/musehub merge dev
muse -C ~/ecosystem/musehub push local main
muse -C ~/ecosystem/musehub push staging main
muse -C ~/ecosystem/musehub push production main
muse -C ~/ecosystem/musehub checkout dev
# 11. Cut the official release against production — the public, linkable one.
muse -C ~/ecosystem/musehub release add v0.4.2
muse -C ~/ecosystem/musehub release push v0.4.2 --hub https://musehub.ai
# Optional — mirror for internal consistency:
muse -C ~/ecosystem/musehub release push v0.4.2 --hub https://staging.musehub.ai
Clean up the feature branch once merged:
muse -C ~/ecosystem/musehub branch -d bump/musehub-v0.4.2
Summary — the one rule that matters
Staging is where the team works. Production is where the world sees it.
Every internal branch, issue, and proposal goes through staging first.
Production only ever receives a push of already-reviewed dev/main
state, plus whatever the public independently opens there — which gets
triaged and re-implemented through staging's normal flow rather than merged
directly.