vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Let the CLI do what the browser does for the same account
7e0b5950c190caf11089e1aaac10f18678074fed · Keenan Nemetz · 6d ago · parent 6e1fca51
Let the CLI do what the browser does for the same account A contributor could file an issue, comment, manage the item it wrote, and open a change from its own branch — but only in the browser, because a push to `refs/heads/vole` required `maintain`. The role was not the reason: the hook had no per-path authorization for that branch, so the role gate stood in for one. The per-path checker is now applied to every session, not only to run credentials. It asks the ACL the questions the browser's forms ask — CanDiscuss, CanOpenRequest, CanTriage, CanApprove — so a contributor's key can write what a contributor may write, and a maintainer's key is unchanged. A non-maintainer's new file must name that account as its author, which is what the browser does for it; a maintainer keeps writing an imported issue under its original author, because that is a trust decision rather than a capability. Creating the issues branch still needs a maintainer, as it does from the browser, and an approval still cannot approve its author's own change — the tree validator already refused that, and now every transport gets the same answer. The one rule that moved is self-approval for a maintainer's push, which is now refused earlier rather than only at the landing gate. With the branch no longer bundled into `maintain`, CONTRIBUTING and the guides stop telling contributors to use the web. Both transports are one authorization model. Part of #168, stacked on #167, which built the checker this generalises.
docs/accounts-and-access.md +13−7
| @@ -362,19 +362,25 @@ vole admin acl runners add demo ci-runner-1 | |||
| 362 | 362 | ## Contributors and their branches | |
| 363 | 363 | ||
| 364 | 364 | The `contribute` role is for open-source repositories that accept outside patches. | |
| 365 | A contributor can read, file issues and comments, and open a change request from | ||
| 366 | the browser. Their Git writes are confined to a branch folder named after their | ||
| 367 | account name: | ||
| 365 | A contributor can read, file issues and comments, manage the items it wrote, and | ||
| 366 | open a change request from a branch it may push — through the CLI or the browser, | ||
| 367 | which apply the same rules. Their Git writes are confined to a branch folder named | ||
| 368 | after their account name: | ||
| 368 | 369 | ||
| 369 | 370 | ```text | |
| 370 | 371 | refs/heads/contrib/<name>/<branch> | |
| 371 | 372 | ``` | |
| 372 | 373 | ||
| 373 | 374 | For example, account `alice` may push `refs/heads/contrib/alice/fix-docs`. They | |
| 374 | cannot push `refs/heads/main`, another account's folder, tags, or the `vole` | ||
| 375 | metadata branch. The pre-receive hook checks the namespace, and rebasing or | ||
| 376 | deleting a branch inside their own folder is allowed because it is not shared | ||
| 377 | history. | ||
| 375 | cannot push `refs/heads/main`, another account's folder, or tags. The pre-receive | ||
| 376 | hook checks the namespace, and rebasing or deleting a branch inside their own | ||
| 377 | folder is allowed because it is not shared history. | ||
| 378 | |||
| 379 | They may also write `refs/heads/vole`, the issues branch, because that is where a | ||
| 380 | comment, an issue, or a change request lives. What the push may contain is the | ||
| 381 | same list the browser offers: a comment, an issue, a change request from their own | ||
| 382 | branch, or a change to an item they wrote. Pre-receive refuses anything else, so | ||
| 383 | the two transports cannot disagree about what a contributor may do. | ||
| 378 | 384 | ||
| 379 | 385 | The namespace is the account name, so a ref says whose work it is without a | |
| 380 | 386 | lookup. It is also why names are fixed at creation: renaming an account would | |