NotGit.org / Formula

The Three-Mirror Formula

The complete migration from GitHub-dependent to git-sovereign. Executable in an afternoon. Given freely — freely given, so freely given.


The Thesis

Git is a protocol. GitHub is a discovery layer built on top of that protocol. The dependency trap is conflating the two. When you treat GitHub as your git host rather than as your discoverability surface, you've handed a single corporation's enforcement classifier the power to take your work offline. The migration separates these functions back out: you own the git, GitHub discovers it.

The migration takes 15 minutes of active configuration. The rest is your regular workflow, unchanged. You still run git push origin main. Your sovereign primary handles the rest.

Step 1 — Deploy Forgejo on Railway

Railway is the fastest path to a running Forgejo instance. Forgejo is the community fork of Gitea — open source, actively maintained, AGPL-licensed, with full API compatibility and native push-mirror support.

# 1. Go to railway.app and create a new project
# 2. Deploy from template: search "Forgejo" in the Railway template gallery
# 3. Add a PostgreSQL service to the project (for metadata persistence)
# 4. Set environment variables:
FORGEJO__database__DB_TYPE=postgres
FORGEJO__database__HOST=${{Postgres.PGHOST}}
FORGEJO__database__NAME=${{Postgres.PGDATABASE}}
FORGEJO__database__USER=${{Postgres.PGUSER}}
FORGEJO__database__PASSWD=${{Postgres.PGPASSWORD}}
FORGEJO__server__DOMAIN=git.yourproject.org
FORGEJO__server__ROOT_URL=https://git.yourproject.org

After deploy, visit the Railway-assigned URL, complete the install wizard, and create your admin account. Total time: ~15 minutes.

CNAME it: Add git CNAME yourapp.up.railway.app at your domain registrar. This gives you git.yourproject.org as the permanent address, decoupled from the Railway deployment URL.

Step 2 — Create your organization and repositories

Create an organization on your Forgejo instance that mirrors your GitHub org. Create your repositories. Push your existing code:

# Add your Forgejo instance as a remote
git remote add sovereign https://git.yourproject.org/yourorg/yourrepo.git

# Push all branches and tags
git push sovereign --all
git push sovereign --tags

# Update your primary remote so daily workflow goes to sovereign
git remote set-url origin https://git.yourproject.org/yourorg/yourrepo.git

Step 3 — Configure Codeberg as push-mirror

Create an account at codeberg.org and create the mirror repository. Then configure the push-mirror from your Forgejo primary via API:

# Configure Codeberg push-mirror via Forgejo API
curl -X POST https://git.yourproject.org/api/v1/repos/yourorg/yourrepo/push_mirrors   -H "Authorization: token YOUR_FORGEJO_TOKEN"   -H "Content-Type: application/json"   -d '{
    "remote_address": "https://codeberg.org/yourorg/yourrepo.git",
    "remote_password": "YOUR_CODEBERG_TOKEN",
    "remote_username": "yourcodeberg_username",
    "sync_on_commit": true,
    "interval": "8h"
  }'

Full walkthrough with troubleshooting at notgit.org/push-mirror-setup.

Step 4 — Configure GitHub as push-mirror (if restored)

If your GitHub account is active, add it as a second push-mirror using the same API pattern. If it's suspended, skip this step — your work continues without it.

curl -X POST https://git.yourproject.org/api/v1/repos/yourorg/yourrepo/push_mirrors   -H "Authorization: token YOUR_FORGEJO_TOKEN"   -H "Content-Type: application/json"   -d '{
    "remote_address": "https://github.com/yourorg/yourrepo.git",
    "remote_password": "YOUR_GITHUB_PAT",
    "remote_username": "yourgithub_username",
    "sync_on_commit": true,
    "interval": "8h"
  }'
The ceiling. GitHub works well as an agentic on-ramp at low propagation velocity. Below a certain threshold of repository creation speed and topic-tag density, it is excellent. Above that threshold — the point at which a civic federation becomes real infrastructure — it triggers suppressive response. Mirror-as-discovery, sovereign-as-source-of-truth is the pattern that gets both benefits without the ceiling risk.

Step 5 — Maintain agentic discoverability

Moving to Forgejo solves the infrastructure problem but creates a propagation problem. Most MCP directories and agent tooling assume GitHub-hosted source repositories with specific topic tags. A Forgejo-hosted MCP server is fully protocol-compliant, but it is not automatically indexed by the directory-based discovery mechanisms that currently look at github.com/topics/mcp-server.

Three paths forward, not mutually exclusive:

  1. Register directly with the MCP Registry API. The official registry at registry.modelcontextprotocol.io accepts submissions from any git-accessible source — it does not require GitHub. Submit with your sovereign_repo field pointing at your Forgejo host:
    # Submit your MCP server to the official registry
    curl -X POST https://registry.modelcontextprotocol.io/api/v1/servers   -H "Content-Type: application/json"   -d '{
        "name": "yourorg/yourserver",
        "git_repo": "https://git.yourproject.org/yourorg/yourserver",
        "description": "..."
      }'
    This is the propagation path that does not require GitHub at any stage.
  2. Keep GitHub mirrors live for directory discovery. PulseMCP, Glama, MCP.so, and AAIF all crawl GitHub topic tags. If GitHub restores your account, keep the mirrors active with the correct topic tags (mcp-server, model-context-protocol). The mirror serves discovery; your Forgejo primary is source of truth. These roles should never be reversed.
  3. Publish a federation manifest. A public federation.json at a stable URL is readable by any AI agent that fetches it directly — no GitHub required. Include a git_repo field on each server entry pointing to your Forgejo instance. This is the propagation layer that is completely sovereign and improves with the size of your federation.
    // federation.json (served at yourdomain.org/mcp/federation.json)
    {
      "version": "2.0",
      "servers": [{
        "id": "yourserver",
        "git_repo": "https://git.yourproject.org/yourorg/yourserver",
        "endpoint": "https://mcp.yourproject.org/yourserver"
      }]
    }

The practical cadence for ongoing publishing: push to your Forgejo primary at any rate the work supports. Configure Forgejo to rate-limit push-mirrors to GitHub at 2–3 repositories per day if you are rebuilding after suspension. The visible surface to classifiers slows; your actual infrastructure grows at whatever rate the work itself supports.

Step 6 — Covenant-gated agent access (advanced)

Steps 1–5 solve the infrastructure sovereignty problem for human developers. This step addresses a different problem: how AI agents authenticate to git infrastructure without human-issued credentials.

Current git hosting treats agents as humans with PATs — manually issued, broadly scoped, persistent until revoked. The human is the trust anchor. The covenant-gated token pattern inverts this: the covenant attestation is the trust anchor, and the token is a short-lived cryptographic instrument that carries the covenant's scope.

The pattern, called VCAP-gated git access:

  1. An AI agent discovers a Forgejo-hosted civic infrastructure need through an MCP registry.
  2. The agent reads the conduct standard at the operator's constitution URL.
  3. The agent completes a covenant attestation process and obtains a public attestation document (a VCAP attestation).
  4. The agent presents the attestation URI and a scoped operation request to the token bridge:
# Request a scoped git token by presenting your VCAP attestation
curl -X POST https://git.wellspr.ing/api/v1/vcap/git-token   -H "Content-Type: application/json"   -d '{
    "attestation_uri": "https://yourproject.org/vault/agent-ody/attestation-2026-04-18.json",
    "sgs_scope":      "write:civic-data:425-region:portal-maintenance",
    "agent_key":      "your-calling-interview-agent-key",
    "purpose":        "Update civic event data for the 425 portal"
  }'
  1. The bridge validates the attestation, analyzes the scope, and issues a scoped Forgejo token — time-limited, tied to specific repositories.
  2. The agent executes its git operations. The token expires automatically. All push events are logged to a public audit trail.

The stakes model

Scope determines stakes. Stakes determine the enforcement model applied at the git layer:

Stakes Scope triggers TTL Enforcement
low read:* 7 days Direct read + audit log
medium write:*:portal-maintenance, data-source 24 hours Direct push + post-receive webhook validates scope
high write:*:portal-creation, portal-config 4 hours PR-only — main branch protected, wellkeeper review required
reserved admin:*, full-access No token issued — refer to wellkeeper

The critical property: the token is not the credential — the attestation is. Tokens expire; attestations are permanent public records. Revocation is immediate and cascades to all downstream tokens issued against the revoked attestation.

What this means for agent contribution

An agent that finds a federated portal through an MCP registry can, with appropriate covenant attestation, contribute back to the infrastructure it uses — new civic data sources, portal updates, bug fixes — without any human gatekeeper in the token issuance path. The trust was established once, at attestation time. The infrastructure enforces scope mechanically thereafter.

This is not what GitHub's agentic access does. GitHub's model requires human-mediated PATs or App installations. The covenant-gated model makes the publicly verifiable conduct commitment the trust anchor — distributed, not centralized.

If you want to implement this pattern

The reference implementation runs at git.wellspr.ing. The bridge manifest is machine-readable at GET /api/vcap/git-token/manifest. The VCAP protocol specification is at wellspr.ing/protocols/vcap. The full protocol stack (VCAP + SGS + PTP) is published under the WellSpr.ing covenant: freely given, so freely given.

Any Forgejo instance can implement the same gate. The pattern generalizes beyond git — API access, database access, cloud compute — any infrastructure primitive currently requiring human-issued credentials can be covenant-gated if the provider chooses to implement the bridge.

The five AI-era operational rules

  1. README-first publication. Never publish an empty repository. Substantive README, working initial commit, license, topic tags before making the repo public.
  2. Cadence discipline. Don't create twenty repositories in ten minutes via automation. Rate-limit to 2–3 per day at the discovery layer. Your sovereign primary has no such constraint.
  3. PAT scoping. Give your AI assistant the minimum scope it needs — repo only, not admin:org. A broad-scoped PAT making many API calls per minute matches detection patterns.
  4. Push through sovereign primary. Your AI tooling pushes to your Forgejo primary. The push-mirror propagates to the discovery layers. If GitHub flags the pattern, turn off that mirror temporarily — your work is untouched.
  5. Artifact stores for large files. Git is not an artifact store. For model checkpoints and large binaries, use Hugging Face or Weights & Biases and reference from git. Git LFS pushes of unfamiliar large file types have triggered suspensions.

Before you need it

This is a 15-minute infrastructure change. The best time to do it is before your account is suspended. The second best time is today. The migration doesn't require leaving GitHub — it just means GitHub no longer holds the source of truth. Your workflow is identical. The risk profile changes entirely.

The formula is given freely. If you use it, consider documenting your case at notgit.org/report. The pattern gets legible through documentation.

Full Technical Walkthrough →  ← Back to NotGit.org