forge: expose forge-side branch protection and check the local mirror against it #122
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/tools#122
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Make the forge-side branch protection rules readable from the agent side, and check the local
protected-branchesfile against them, so the git rails derive from the authoritative fact instead of duplicating it. Today the forge rule is the wall that actually rejects a push,protected-branchesis a hand-maintained mirror of it, and nothing detects when the two disagree.Primary goals:
forgecommand reports whether a repo's branch is protected and whether the current token may push it, using the endpoint a non-admin token can actually read.protected-branchesentry against the forge and fail loud on disagreement in either direction: a locally-protected branch the forge does not protect, and a forge-protected branch the local file omits.Current state
forgehas no branch-protection command. The obvious endpoint is closed to agents:GET /api/v1/repos/{owner}/{repo}/branch_protectionsreturns 403 withuser should be an owner or a collaborator with admin write of a repository, because the agent token carriespushbut notadmin.GET /api/v1/repos/{owner}/{repo}/branches/{branch}is readable with that same token and carries what the rails need —protectedanduser_can_push. Verified across the org: the eight repos listed in~/.config/git/protected-branchesall returnprotected: true, user_can_push: false, andallod/memoryandallod/strategyreturnfalseandtrue. That is an exact match with the local file today, which is precisely why drift would be invisible until a push failed or a rail silently stopped firing.The plumbing already exists.
forge:54resolvesFORGE_URL, and the shared request helper atforge:244attaches the token throughcurl --configso it never reaches child argv, per the token-handling rule inallod/memorysecurity-practices.md.Suggested shape
forge repo protection [<owner/repo>]prints the effective status for the repo's default branch, defaulting to the repo containing$PWDlike the otherforgecommands.forge repo protection --checkwalks every entry inprotected-branches, compares each against the forge, and exits non-zero listing any disagreement.The alternative siting for the check half is a
workspace/script alongside the other cross-repo tools, sinceprotected-branchesis consumed byallodandgit-hooks/protected-refs-policyrather than byforge. Default to theforgesubcommand because the comparison needs the API client and the authority being checked is the forge's; move it only if the check grows workspace-wide concerns.Relationship to the rails
This does not replace the path-vs-remote-identity work in allod/tools#112. That issue fixes how the rails look a repo up; this one checks that what they look up still matches the forge. They compose: allod/tools#112's remote-identity key is what makes a per-repo comparison well-defined, since it is the same
owner/repoderivation the check needs.Scope
In: a new read-only
forgesubcommand, its help text, and tests against a stubbed API. Out: any command that changes protection rules; thebranch_protectionsadmin endpoint; the remote-identity lookup change in allod/tools#112; and changing the contents ofprotected-branches, which stays a human edit.