feat(gitmirrors): declare sean/ex-mcp and give it a real-time codeberg backup #674

Merged
binjovi-bot merged 1 commit from feat/onboard-ex-mcp into trunk 2026-09-12 14:07:57 +00:00
Owner

Why

Binjovi builds its own MCP server from sean/ex_mcpapps/binjovi_api/mix.exs pins it by git ref. It had no ForgejoRepository, no ForgejoPushMirror and no backup of any kind. make rebuild wipes Forgejo, so the next rebuild would have destroyed the source of Binjovi's MCP server, exactly as sean/linux was lost on 2026-05-31.

The fork itself is already safe — codeberg.org/someara/ex-mcp was seeded first, 46 refs, verified identical. This makes the backup declared and continuous instead of a one-off I did by hand.

The rename

sean/ex_mcpsean/ex-mcp. ProjectRegistry validates a project name with valid_dns_name? (\A[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?\z), which rejects _, and several schema clauses assert repo == "sean/<project>". The Hex application stays :ex_mcp; only the repository is renamed.

Forgejo's redirect keeps the old clone URL working, so Binjovi's pin does not break before its own change lands — confirmed with git ls-remote and again by a clean mix deps.get, which still resolves ex_mcp.git.

Branch Role
master tracks upstream ExMCP
trunk protected integration; now the repository default
main release head

All three are in branchFilter and all three exist — a filter naming an absent branch fails the whole push atomically.

The onboarding cost, made visible

Two separate allowlists had to learn the name, which is exactly the friction this programme is meant to remove:

  • the release-train rebase case in tests/gitmirror-fleet.sh
  • the forgejopushmirrors grant in binjovi/service-legacy-access.yaml, whose guard requires set equality with the fleet

A false positive, fixed

The reconciler from #670 read only gitmirrors/, so binjovi-plans and hetzner-node-image looked unbacked. They are not — their mirrors moved to Binjovi and are recorded in tests/binjovi-owned-mirrors.txt. It now reads that ledger, taking column 2 where it names a repository, because ibmi-examples (mirror of rpg-hello) and zerotierone (mirror of ZeroTierOne) prove the two columns differ.

pipelines and pipelines-operator are exempted with evidence, not by assumption. Both belong to the retired system, and codeberg holds a strict superset of their Forgejo refs:

pipelines           forgejo 765 refs | codeberg 1166 | Forgejo-only: 0
pipelines-operator  forgejo 154 refs | codeberg  193 | Forgejo-only: 0

The failure message now tells the next reader to run that same superset check before exempting anything.

Verification

gitmirror-fleet          ok: 37 mirrors, 37 real-time push mirrors
binjovi-service-handoff  PASS
forgejo-repo-reconcile   ok: 43 live, 37 declared, 6 exempt
tests/check.sh           green

The reconciler is green for the first time. That matters: a report that is permanently red is a report nobody reads.

Still to come: the Binjovi schema generation and catalog record that make ex-mcp a build-and-tag project.

https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6

## Why Binjovi builds its own MCP server from `sean/ex_mcp` — `apps/binjovi_api/mix.exs` pins it by git ref. It had **no** `ForgejoRepository`, **no** `ForgejoPushMirror` and no backup of any kind. `make rebuild` wipes Forgejo, so the next rebuild would have destroyed the source of Binjovi's MCP server, exactly as `sean/linux` was lost on 2026-05-31. The fork itself is already safe — `codeberg.org/someara/ex-mcp` was seeded first, 46 refs, verified identical. This makes the backup **declared and continuous** instead of a one-off I did by hand. ## The rename `sean/ex_mcp` → `sean/ex-mcp`. `ProjectRegistry` validates a project name with `valid_dns_name?` (`\A[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?\z`), which rejects `_`, and several schema clauses assert `repo == "sean/<project>"`. The Hex application stays `:ex_mcp`; only the repository is renamed. Forgejo's redirect keeps the old clone URL working, so Binjovi's pin does not break before its own change lands — confirmed with `git ls-remote` and again by a clean `mix deps.get`, which still resolves `ex_mcp.git`. | Branch | Role | | --- | --- | | `master` | tracks upstream ExMCP | | `trunk` | protected integration; now the repository default | | `main` | release head | All three are in `branchFilter` and all three exist — a filter naming an absent branch fails the whole push **atomically**. ## The onboarding cost, made visible Two separate allowlists had to learn the name, which is exactly the friction this programme is meant to remove: - the release-train rebase case in `tests/gitmirror-fleet.sh` - the `forgejopushmirrors` grant in `binjovi/service-legacy-access.yaml`, whose guard requires **set equality** with the fleet ## A false positive, fixed The reconciler from #670 read only `gitmirrors/`, so `binjovi-plans` and `hetzner-node-image` looked unbacked. They are not — their mirrors moved to Binjovi and are recorded in `tests/binjovi-owned-mirrors.txt`. It now reads that ledger, taking column 2 where it names a repository, because `ibmi-examples` (mirror of `rpg-hello`) and `zerotierone` (mirror of `ZeroTierOne`) prove the two columns differ. `pipelines` and `pipelines-operator` are exempted **with evidence**, not by assumption. Both belong to the retired system, and codeberg holds a strict superset of their Forgejo refs: ``` pipelines forgejo 765 refs | codeberg 1166 | Forgejo-only: 0 pipelines-operator forgejo 154 refs | codeberg 193 | Forgejo-only: 0 ``` The failure message now tells the next reader to run that same superset check before exempting anything. ## Verification ``` gitmirror-fleet ok: 37 mirrors, 37 real-time push mirrors binjovi-service-handoff PASS forgejo-repo-reconcile ok: 43 live, 37 declared, 6 exempt tests/check.sh green ``` The reconciler is green for the first time. That matters: a report that is permanently red is a report nobody reads. Still to come: the Binjovi schema generation and catalog record that make `ex-mcp` a build-and-tag project. https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6
feat(gitmirrors): declare sean/ex-mcp and give it a real-time codeberg backup
All checks were successful
binjovi/ci Binjovi completed the frozen plan
3f946a6827
Binjovi builds its own MCP server from this repository: apps/binjovi_api/mix.exs
pins it by git ref. Until now it had no ForgejoRepository, no ForgejoPushMirror
and no backup of any kind, so `make rebuild` would have destroyed the source of
Binjovi's MCP server. That is how sean/linux was lost on 2026-05-31.

RENAME. sean/ex_mcp is now sean/ex-mcp. ProjectRegistry validates a project
name with valid_dns_name?, which rejects `_`, and several schema clauses assert
repo == "sean/<project>". The Hex application stays :ex_mcp; only the
repository is renamed. Forgejo's redirect keeps the old clone URL working, so
Binjovi's pin does not break before its own change lands.

BRANCHES. master tracks upstream, trunk is the protected integration branch and
now the repository default, main is the release head. All three are named in
branchFilter and all three exist -- a filter naming an absent branch fails the
whole push atomically.

Two allowlists had to learn the name, which is the onboarding cost this work is
meant to reduce: the release-train rebase case in tests/gitmirror-fleet.sh, and
the forgejopushmirrors grant in binjovi/service-legacy-access.yaml, whose guard
requires set equality with the fleet.

Also fixes a false positive in tests/forgejo-repo-reconcile/run-all.sh. It read
only gitmirrors/, so binjovi-plans and hetzner-node-image -- whose mirrors moved
to Binjovi and are recorded in tests/binjovi-owned-mirrors.txt -- looked
unbacked. They are not. It now reads that ledger, taking column 2 where it names
a repository, because ibmi-examples and zerotierone prove the columns differ.
pipelines and pipelines-operator are exempted with evidence: both belong to the
retired system, and codeberg holds a strict SUPERSET of their Forgejo refs
(1166 vs 765, 193 vs 154, zero Forgejo-only refs, checked 2026-09-12). The
report now reads green, which is the only state in which red means anything.

Claude-Session: https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6
binjovi-bot deleted branch feat/onboard-ex-mcp 2026-09-12 14:07:57 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
sean/seanfarm!674
No description provided.