Muse ↔ GitHub history reconciliation — June 2026
Status: COMPLETE — Muse main is canonical again, GitHub main and Muse main hold the
identical tree, and the muse-mirror workflow is safe to use.
Simple summary: for a few days the project had two slightly different "latest versions" — the one tracked by Muse (our canonical history) and the one on GitHub (where two emergency fixes had to ship directly to production). This document records how the two were brought back to a single identical version, with the GitHub-only emergency work imported into Muse so nothing was lost.
Technical summary: GitHub main had four changes absent from Muse (8ae04be RBAC
proposal-approval fix + companion app phases 1-6 + MCP OAuth C3/C5 hardening; d5cfe77 AGENTS.md
muse-mirror mandate; PR #229 hosted MCP discovery timeout hotfix; PR #230 frontmatter
normalization hotfix). Muse main had one commit absent from GitHub's local clone
(6f47d53a, hosted discovery fix) — which turned out to be byte-identical to PR #229's content.
origin/main was verified to be a strict superset of the Muse working tree, so reconciliation
was a content import of origin/main into Muse, committed as one reconciliation commit, then
mirrored back through the standard muse-mirror PR.
Why this was shelved, and why it is now resolved
On 2026-06-08, two hotfixes had to ship straight from GitHub main to production (Netlify
gateway/bridge). The standing instruction was: do not run muse-mirror until reconciled,
because mirroring the then-current Muse snapshot would have deleted the GitHub-only
companion/native-OAuth files and their test suites from production. Those hotfixes shipped;
this reconciliation closes the gap.
Divergence inventory (evidence captured 2026-06-10)
State before reconciliation:
| Check | Result |
|---|---|
muse status |
clean; HEAD 6f47d53a ("fix(mcp): bound hosted discovery context", 2026-06-08) |
local git main |
583a091 (merge of PR #228); strictly behind origin/main (ff possible) |
origin/main |
24051c2 (merge of PR #230) |
git diff origin/main (working tree = Muse main) |
107 D / 18 M; 2 untracked |
| GitHub-only commits | 8ae04be, d5cfe77, PR #229 (0f34ff3), PR #230 (24051c2) — all confirmed present on origin/main |
Working-tree-only ("Muse-only") added lines vs origin/main |
99 lines across 13 files — every line inspected; all were older shapes superseded by origin/main (see below) |
The 107 "deletions" were divergence artifacts, not uncommitted work: companion app libs
(lib/companion-*.mjs, lib/model-runtime-lane.mjs), native OAuth provider
(hub/gateway/native-oauth-provider.mjs, native-as-store.mjs), companion design docs
(docs/COMPANION-APP-*.md), and the seven-tier test suites for companion,
native-oauth-c1-c6, proposal-approve-rbac-fix, model-runtime-lane, derived-artifact-storage,
and llm-complete-openrouter.
Findings that shaped the resolution
1. The MCP discovery "overlap hazard" was already resolved upstream
Muse 6f47d53a and GitHub PR #229 were suspected to be independent implementations of the same
hosted MCP discovery fix. Byte-level comparison showed they are the same implementation:
hub/bridge/server.mjs, hub/gateway/mcp-proxy.mjs, test/bridge-hosted-context-settings.test.mjs,
test/gateway-settings-hosted-vault-filter.test.mjs, and test/mcp-gateway-proxy.test.mjs all
diff zero between the Muse working tree and origin/main. One implementation; nothing to
delete. This also means the Muse-only hosted-context settings endpoint
(GET /api/v1/hosted-context/settings) and gateway delegated vault filtering were already in
production via PR #229.
2. OpenRouter/chat-provider was never deliberately removed in Muse
muse log --all shows the OpenRouter/chat-provider work lives on the unmerged Muse branch
feat/companion-design-openrouter-lane (commits 3b70a5eb, 7c3a895f, branched from
f4def6a1). It reached GitHub main when that branch was mirrored as ca1f023 (PR #227).
Muse main never contained it, so there is no deliberate Muse removal commit. Per the
reconciliation rule ("keep the Muse-side removal only if a deliberate Muse commit confirms it"),
the OpenRouter/chat-provider code was restored from GitHub.
FLAGGED FOR SEPARATE DECISION: the OpenRouter/chat-provider lane is now in Muse canonical history via the reconciliation commit, but the owner has not explicitly merged
feat/companion-design-openrouter-laneinto Musemain. If removal is wanted, it must be its own documented Muse commit through the normal flow.
3. origin/main is a strict superset of Muse main
All 99 working-tree-only lines were individually inspected. Each is an older shape that
origin/main superseded:
| File | Muse-only lines were… | Superseded by |
|---|---|---|
lib/llm-complete.mjs (53) |
pre-OpenRouter provider docs + Ollama path | OpenRouter lane (superset; DeepInfra/Ollama retained) |
web/hub/hub.js (14) |
approve/discard errors appended to detail-body |
8ae04be showToast error surfacing |
lib/daemon-llm.mjs (7) |
pre-OpenRouter model-override merge | OpenRouter-aware version |
mcp/tools/index-enrich.mjs (6) |
simple ai_summary write, skip failures |
enrich audit lane |
test/gateway-auth-refresh-wiring.test.mjs (5) |
offset-window (slice(g, g+600)) assertions |
routeBlock helper matching 8ae04be server shape |
hub/gateway/server.mjs (3) |
pre-normalization note read; pre-fallback role | PR #230 frontmatter normalization; 8ae04be RBAC fallback |
.env.example (3) |
pre-OpenRouter provider notes | OpenRouter lane docs |
lib/memory-consolidate.mjs (2) |
direct mm.store('insight', …) |
Phase 6 (D6.6.2) DerivedArtifactWriter routing |
docs/HUB-API.md (2) |
pre-normalization GET /notes/:path doc | PR #230 doc update |
hub/gateway/mcp-oauth-provider.mjs (1) |
exchangeAuthorizationCode ignoring redirect_uri |
C5 (RFC 6749 §4.1.3) validation + C3 (RFC 9207) iss |
web/hub/hub-integration-guides.mjs (1) |
2-kind typedef | provider kind (OpenRouter tile) |
hub/server.mjs (1) |
plain loadConfig import |
loadConfig, CHAT_PROVIDERS, normalizeChatProviderInput |
AGENTS.md (1) |
curly-quote variant of one line | d5cfe77 muse-mirror mandate section |
Conclusion: importing origin/main's tree loses zero unique Muse work.
Conflict resolutions (as planned, with outcomes)
| Planned conflict | Outcome |
|---|---|
AGENTS.md — keep d5cfe77 mandate |
Kept (origin side) |
hub/gateway/mcp-oauth-provider.mjs — keep C3/C5 |
Kept (origin side; iss emit at L160, redirect_uri mismatch reject at L183) |
hub/gateway/server.mjs + web/hub/hub.js — keep 8ae04be RBAC fallbacks + toasts, merged with hosted-context |
Kept; hosted-context changes were already merged on origin via PR #229 |
| MCP discovery — keep one implementation | Already one implementation (byte-identical) |
| OpenRouter — keep Muse removal only if deliberate | Not deliberate (unmerged branch); restored from GitHub, flagged above |
What was done
git fetch origin; recorded the full divergence inventory before changing anything.git checkout origin/main -- .— imported the GitHub-only content into the working tree. Verifiedgit diff origin/mainis empty (tree identity).- Ran the full test suite (
npm test, includes the restored seven-tier companion / native-oauth / RBAC / openrouter suites) — all green. - Muse reconciliation commit on
mainimporting the GitHub-direct history, including this document. - Local git
mainfast-forwarded toorigin/main(git reset --mixed; pointer-only, no content change, no history rewrite). - Mirrored Muse
main→ GitHub via the standardmuse-mirrorbranch + PR (this document is the only file-level delta on the GitHub side, shipped in the same PR as the Muse code import it records). - Verified GitHub
maintree == Musemainsnapshot (empty diff).
Seven-tier coverage for the merged surface
The merged hosted-context + restored-RBAC/OAuth surface is covered by restored and existing suites, all green in step 3:
- Unit / Integration / E2E / Stress / Data-integrity / Performance / Security:
test/proposal-approve-rbac-fix-*.test.mjs(7 tiers, RBAC fallback decision paths),test/native-oauth-c1-c6-*.test.mjs(7 tiers, code-exchange validation,iss,redirect_urimismatch, sessionless MCP rejection),test/companion-*-{unit,integration,e2e,stress,data-integrity,performance,security}.test.mjs,test/llm-complete-openrouter-*.test.mjs(7 tiers),test/derived-artifact-storage-*.test.mjs(7 tiers),test/model-runtime-lane-*.test.mjs(7 tiers). - Hosted-context settings + vault filtering:
test/bridge-hosted-context-settings.test.mjs,test/gateway-settings-hosted-vault-filter.test.mjs(allowlist never widens; 403 → empty allowlist; forgedX-User-Idrejected; no canister enumeration with explicit delegated IDs; 60s-cache budget),test/mcp-gateway-proxy.test.mjs. - Frontmatter normalization:
test/gateway-hosted-notes-frontmatter.test.mjs.
Current operating procedure (unchanged, now unblocked)
- Develop on a Muse feature branch; merge to Muse
mainafter tests are green. - Mirror every Muse
mainmerge to GitHub via themuse-mirrorbranch + PR (mandated inAGENTS.md; never push directly to GitHubmain). - Deploy follows GitHub
main(Netlify).
Do not reopen this reconciliation unless a future status check proves Muse main and GitHub
main have diverged again.
Exit criteria
- [x]
muse statusclean after the reconciliation commit. - [x]
git statusclean; localmain==origin/main. - [x] GitHub
maintree == Musemainsnapshot (empty file-level diff). - [x] Full suite green on the reconciled tree.
- [x] Production verified (live probes, 2026-06-10): gateway healthy;
GET /api/v1/hosted-context/settingslive and 401s both unauthenticated and forgedX-User-Idrequests; OAuth discovery serves the canonical issuer; token exchange rejects malformed requests (400invalid_request); sessionless MCP non-initialize rejected (-32600 / 401). Theredirect_uri-mismatch and delegated-vault-visibility paths require valid credentials to probe live; they are verified by the greennative-oauth-c1-c6-securityandgateway-settings-hosted-vault-filtersuites against the identical tree that is deployed. - [x] This document merged with the code in the same PR.
Related documents
docs/COMPANION-APP-OAUTH-SERVERSIDE-GATE.md— C1–C6 OAuth hardening contract (C3/C5 shipped).docs/COMPANION-APP-PHASE-*.md— companion app phases 1-6 (restored to Muse canonical).docs/HUB-API.md— frontmatter normalization contract (PR #230).- Scooling
docs/GITHUB-MIRROR-RECONCILIATION-FOLLOWUP.md— the model for this record.