gabriel / muse public
bridge-ci.md markdown
213 lines 5.2 KB
Raw
sha256:51ce277f663e01a43eaffbe77509b1de7ac2d4251b55d23306304bcdeb92c90d feat(pack): delta-encode snapshots in MPackBundle wire format Sonnet 4.6 minor ⚠ breaking 121 days ago

muse bridge — CI Authentication & Usage

Overview

muse bridge provides bidirectional Git interoperability for Muse repositories. This document covers CI setup, environment variables, and usage patterns for automated mirror workflows.

Environment Variables

Variable Purpose
MUSE_AGENT_KEY PEM-encoded Ed25519 private key (agent identity)
MUSE_AGENT_HANDLE Registered Muse agent handle
GIT_AUTHOR_EMAIL Override git commit author email for exports
GIT_AUTHOR_NAME Override git commit author name
GIT_COMMITTER_EMAIL Override git committer email
GIT_COMMITTER_NAME Override git committer name

.muse/git-bridge.toml — Bridge State File

Bridge state is persisted in .muse/git-bridge.toml. It records the last successful import and export sync points. Add this file to .museignore to keep per-developer state out of the Muse object store:

# .museignore
.muse/git-bridge.toml

Structure

[last_import]
git_sha = "abc123..."          # 40-char SHA-1 of last imported git commit
git_ref = "main"               # git branch imported
muse_commit_id = "sha256:..."  # Muse commit ID created by import
imported_at = "2026-04-14T10:00:00Z"

[last_export]
muse_commit_id = "sha256:..."  # Muse commit ID that was exported
git_ref = "muse-mirror"        # git branch written to
git_sha = "def456..."          # git commit SHA created by export
exported_at = "2026-04-14T09:55:00Z"

Subcommand Reference

muse bridge git-import

Import git commits into a Muse repository:

muse bridge git-import /path/to/git-repo \
  --branch main \
  --incremental \
  --attribution-map /path/to/authors.json \
  --sign \
  --json

muse bridge git-export

Export a Muse snapshot into a git working tree:

muse bridge git-export \
  --git-dir /path/to/git-mirror \
  --git-branch muse-mirror \
  --git-remote origin \
  --no-push \
  --json

muse bridge git-status

Show bridge state and drift counts:

muse bridge git-status --git-dir /path/to/git-repo --json

Output:

{
  "last_import": {"git_sha": "...", "git_ref": "main", ...},
  "last_export": {"muse_commit_id": "sha256:...", "git_ref": "muse-mirror", ...},
  "drift": {
    "git_commits_since_import": 3,
    "muse_commits_since_export": 1
  }
}

--watch mode

Poll Muse HEAD every N seconds and auto-export on new commits:

muse bridge git-export \
  --git-dir /path/to/git-mirror \
  --git-branch muse-mirror \
  --no-push \
  --watch 30 \
  --json

Each poll emits a NDJSON event:

{"event": "poll", "muse_commit_id": "sha256:...", "changed": false}
{"event": "exported", "muse_commit_id": "sha256:...", "git_sha": "abc..."}

GitHub Actions Example

name: Mirror to Git
on:
  push:
    branches: [main]

jobs:
  mirror:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install muse
        run: pip install muse-vcs
      - name: Export to git mirror
        env:
          MUSE_AGENT_KEY: ${{ secrets.MUSE_AGENT_KEY }}
          MUSE_AGENT_HANDLE: ${{ secrets.MUSE_AGENT_HANDLE }}
        run: |
          muse bridge git-export \
            --git-dir /tmp/git-mirror \
            --git-branch muse-mirror \
            --git-remote origin \
            --no-push \
            --json

CircleCI Example

version: 2.1

jobs:
  mirror-to-git:
    docker:
      - image: cimg/python:3.12
    steps:
      - checkout
      - run:
          name: Install muse
          command: pip install muse-vcs
      - run:
          name: Export Muse snapshot to git mirror
          command: |
            muse bridge git-export \
              --git-dir /tmp/git-mirror \
              --git-branch muse-mirror \
              --git-remote origin \
              --no-push \
              --json
          environment:
            MUSE_AGENT_KEY: << pipeline.parameters.muse_agent_key >>
            MUSE_AGENT_HANDLE: muse-ci-bot

workflows:
  mirror:
    jobs:
      - mirror-to-git:
          filters:
            branches:
              only: [main]

Attribution Map

When importing git commits, map git author emails to Muse handles:

{
  "[email protected]": "alice",
  "[email protected]": "bob",
  "[email protected]": "ci-bot"
}

Unmapped emails receive a synthetic handle: git-import/<sha256[:8]>.

Pass the map file with --attribution-map:

muse bridge git-import /path/to/git-repo \
  --attribution-map /path/to/authors.json \
  --sign \
  --json

Security Notes

  • All subprocess calls use argument lists — shell=True is never used.
  • --git-branch is validated against a safe-character regex before any subprocess call. Characters ;, &, |, `, $, (, ), spaces, and control chars are rejected.
  • Git SHA-1 values are validated (40 lowercase hex chars) before being passed to git cat-file. Invalid SHAs raise ValueError rather than reaching the subprocess.
  • Attribution handles are stripped of ASCII control characters on load.
  • Bridge state is written atomically (temp-file + rename) with a module-level lock.
  • muse_commit_id values are validated for the sha256: prefix at the persistence boundary — bare hex strings are never stored.
File History 1 commit
sha256:51ce277f663e01a43eaffbe77509b1de7ac2d4251b55d23306304bcdeb92c90d feat(pack): delta-encode snapshots in MPackBundle wire format Sonnet 4.6 minor 121 days ago