feat(binjovi): seed ex-mcp management grant and authority readback #680

Merged
binjovi-bot merged 1 commit from feat/ex-mcp-authority into trunk 2026-09-12 16:11:23 +00:00
Owner

Why

Two grants the bindings change missed. Both surfaced by watching the live bootstrap fail, not by reading the tree — neither is visible from the binding lists.

The management grant

binjovi-operator-bot is a non-admin Forgejo user, and CollaboratorClient.repository_access/2 refuses any repository whose permissions.admin is not true. So it cannot grant itself the access it needs.

Every ex-mcp service operation sat at denied, attempt 5, while the identical operations on bytey succeeded — because bytey already carries both bots:

sean/bytey    collaborators: ['binjovi-bot', 'binjovi-operator-bot']
sean/ex-mcp   collaborators: []

management-grants-repositories.txt is the mechanism. Its Job PUTs binjovi-operator-bot onto each listed repository with the admin token, and its guard states the rule: "every cold-rebuild seed needs its management grant before Binjovi can adopt it." 40 → 41 entries.

Flux may not make that grant instead. tests/binjovi-collaborator-handoff.sh forbids a ForgejoCollaborator CR for binjovi-bot or binjovi-operator-bot in forgejo-users or gitmirrors. I wrote those CRs first; the guard rejected them and was right to.

The authority readback

binjovi-provider-authority in execution-platform.yaml gains ex-mcp-main, ex-mcp-trunk, ex-mcp-tags.

It is a different Role from binjovi-service-legacy — the pre-release authority check, not the absence check — and both bind the same ServiceAccount. That is exactly why granting one looked sufficient and was not. Worth knowing for the next onboarding.

Known blocker — not introduced here

The grant Job cannot run today, so this change does not by itself grant ex-mcp anything.

binjovi-management-grants-bootstrap-v2   exec /bin/sh: exec format error
                                         13 failed pods over 21h

Its image registry.sean.farm/someara/pipeline-tools:v8 is pinned by digest, which pins a single architecture rather than a manifest list — and all six nodes are now arm64. The binfmt DaemonSet that would emulate it is nodeSelector: kubernetes.io/arch=amd64 with 0 desired, because no amd64 node remains.

buildkit-fleet-retire in ns argocd dies on the same image the same way. This is a live fault affecting more than this work and it is not mine to fix.

Two consequences worth stating plainly:

  • This change makes the seed correct for a cold rebuild and for whenever the image is repaired.
  • Editing the list does not re-run the Job. Jobs are immutable, so the -v2 suffix must move once the image works.

Verification

Full tests/check.sh green. The bootstrap guard moves 40 → 41 and now asserts ex-mcp by name.

https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6

## Why Two grants the bindings change missed. Both surfaced by watching the live bootstrap fail, not by reading the tree — neither is visible from the binding lists. ## The management grant `binjovi-operator-bot` is a **non-admin** Forgejo user, and `CollaboratorClient.repository_access/2` refuses any repository whose `permissions.admin` is not true. So it cannot grant itself the access it needs. Every `ex-mcp` service operation sat at `denied`, attempt 5, while the identical operations on `bytey` succeeded — because bytey already carries both bots: ``` sean/bytey collaborators: ['binjovi-bot', 'binjovi-operator-bot'] sean/ex-mcp collaborators: [] ``` `management-grants-repositories.txt` is the mechanism. Its Job `PUT`s `binjovi-operator-bot` onto each listed repository with the admin token, and its guard states the rule: *"every cold-rebuild seed needs its management grant before Binjovi can adopt it."* **40 → 41 entries.** **Flux may not make that grant instead.** `tests/binjovi-collaborator-handoff.sh` forbids a `ForgejoCollaborator` CR for `binjovi-bot` or `binjovi-operator-bot` in `forgejo-users` or `gitmirrors`. I wrote those CRs first; the guard rejected them and was right to. ## The authority readback `binjovi-provider-authority` in `execution-platform.yaml` gains `ex-mcp-main`, `ex-mcp-trunk`, `ex-mcp-tags`. It is a **different Role** from `binjovi-service-legacy` — the pre-release authority check, not the absence check — and both bind the same ServiceAccount. That is exactly why granting one looked sufficient and was not. Worth knowing for the next onboarding. ## Known blocker — not introduced here **The grant Job cannot run today**, so this change does not by itself grant `ex-mcp` anything. ``` binjovi-management-grants-bootstrap-v2 exec /bin/sh: exec format error 13 failed pods over 21h ``` Its image `registry.sean.farm/someara/pipeline-tools:v8` is pinned **by digest**, which pins a single architecture rather than a manifest list — and all six nodes are now `arm64`. The `binfmt` DaemonSet that would emulate it is `nodeSelector: kubernetes.io/arch=amd64` with **0 desired**, because no amd64 node remains. `buildkit-fleet-retire` in ns `argocd` dies on the same image the same way. **This is a live fault affecting more than this work and it is not mine to fix.** Two consequences worth stating plainly: - This change makes the seed correct for a cold rebuild and for whenever the image is repaired. - Editing the list does **not** re-run the Job. Jobs are immutable, so the `-v2` suffix must move once the image works. ## Verification Full `tests/check.sh` green. The bootstrap guard moves 40 → 41 and now asserts `ex-mcp` by name. https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6
feat(binjovi): seed ex-mcp's management grant and authority readback
All checks were successful
binjovi/ci Binjovi completed the frozen plan
5b50cc5cac
Two grants the previous change missed. Both were found by watching the live
bootstrap fail, not by reading the tree, and neither is visible from the
binding lists alone.

THE MANAGEMENT GRANT. binjovi-operator-bot is a non-admin Forgejo user, and
CollaboratorClient.repository_access/2 refuses any repository whose
permissions.admin is not true. It therefore cannot grant itself the access it
needs. Every ex-mcp service operation sat at `denied`, attempt 5, while the
identical operations on bytey succeeded -- because bytey already carries both
bots. management-grants-repositories.txt is the mechanism that closes this:
its Job PUTs binjovi-operator-bot onto each listed repository with the admin
token. Its own guard states the rule: "every cold-rebuild seed needs its
management grant before Binjovi can adopt it." 40 -> 41 entries.

Flux may NOT make that grant instead. tests/binjovi-collaborator-handoff.sh
forbids a ForgejoCollaborator CR for binjovi-bot or binjovi-operator-bot in
forgejo-users or gitmirrors. I wrote those CRs first; the guard rejected them
and was right to.

THE AUTHORITY READBACK. binjovi-provider-authority in execution-platform.yaml
gains ex-mcp-main, ex-mcp-trunk and ex-mcp-tags. It is a DIFFERENT Role from
binjovi-service-legacy -- the pre-release authority check rather than the
absence check -- and both bind the same ServiceAccount, which is exactly why
granting one looked like enough.

KNOWN BLOCKER, NOT INTRODUCED HERE. The grant Job cannot run today.
binjovi-management-grants-bootstrap-v2 fails `exec /bin/sh: exec format error`
on every attempt, 13 failed pods over 21 hours. Its image
registry.sean.farm/someara/pipeline-tools:v8 is pinned by DIGEST, which pins a
single architecture rather than a manifest list, and all six nodes are now
arm64. The binfmt DaemonSet that would emulate it is
nodeSelector kubernetes.io/arch=amd64 with 0 desired, because no amd64 node
remains. buildkit-fleet-retire in ns argocd dies on the same image the same
way. This change makes the seed correct for a cold rebuild and for whenever
that image is repaired; it does not by itself grant ex-mcp anything. Nor does
editing the list re-run the Job: Jobs are immutable, so the -v2 suffix must
move once the image works.

Full tests/check.sh green.

Claude-Session: https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6
binjovi-bot deleted branch feat/ex-mcp-authority 2026-09-12 16:11:24 +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!680
No description provided.