Branches, not pull requests
amadan has no pull request object. This is the difference most likely to trip you up coming from GitHub, and it is deliberate rather than unfinished.
The short version#
On GitHub, a branch is raw material and the pull request is the thing you actually work with — it holds the title, the description, the review, the conversation, the checklist, the CI results, and the merge button. Delete the branch and the PR survives as the record.
On amadan the branch itself carries all of that. There is no second object to open, no "create pull request" step, and nothing that has to be opened before people can talk about the work.
You push a branch. It has a page. That page is where the work lives.
What a branch carries#
- A description. The equivalent of a PR body: what this branch is for. Editable by any member, from the branch page or with
amadan branch describe. - Its commits. With CI status against each one.
- A review view. The full diff against the default branch, with a file-by-file table of contents.
- Discussions. Threads attached to this branch specifically.
- Tasks. An ordered checklist moving through a status ladder.
- Prompt ledger entries, where the repo has the ledger enabled — the prompts behind the AI-assisted commits on this branch.
Merging#
The branch page has a Merge button, and anyone with write access to the repo sees it. It makes an ordinary merge commit with two parents on the default branch. From a terminal it is amadan branch merge, which takes the same route and answers to the same gate.
It will not squash and it will not fast-forward. Both would break the record: amadan works out that a branch landed by asking git whether its tip is an ancestor of the default tip, and a squash rewrites the commits so the answer comes back no.
Merging deletes the branch unless you untick the box, which sounds worse than it is. The vanished head is how a branch comes to read Merged — its last sha is kept as a tombstone, and that sha is now an ancestor of the default tip — and the description, tasks and discussions are stored against the branch name, so the page outlives the ref.
CI can refuse it#
An owner can turn on Require a green CI run under the repo's Merge gate settings. It's off by default. With it on, the button is replaced by the reason it isn't there: the tip's CI is failing, or still running, or has never run. "Never run" counts as not green, so switching this on for a repo with no .amadan/ci script blocks every merge until there is one.
Two things it deliberately does not do. It checks the branch tip, not the merge result — if something else lands on the default branch after the check, that isn't covered, and the card says so above the button. And it governs the button only. A writer can still git push straight to the default branch, and nothing here stops them. This is a gate, not branch protection.
On the encrypted tier you still merge with git#
private_e2ee is the exception, and it's arithmetic rather than a feature nobody got round to. The server holds sealed packs it cannot read, so there is no tree for it to three-way merge and no honest way to fake one. There is no button on that tier.
git checkout main
git merge my-branch
git pushMerging an encrypted repo has to happen somewhere that holds the repo key, which today means your machine. The branch view says so where you would have looked for the button, with those three lines filled in for the branch you are on — you shouldn't have to read this page to find out.
Active and Closed#
The Branches tab has two filters, and they behave like GitHub's open and closed PR lists.
Active — live branches that haven't been merged and haven't been archived. What you're working on.
Closed — everything else, newest activity first, each row tagged with why it's there:
- merged — the tip is an ancestor of the default branch. Derived from git on the fly; nothing is stored.
- archived — somebody explicitly closed it without merging. This is the "close this PR, we're not doing it" action. Reversible.
- deleted — the ref is gone, but the records aren't.
That last one is the important one.
Deleting a branch does not delete the conversation#
A branch's description, discussions and tasks are stored against the branch name, not against the git ref. Delete the ref and the page survives, showing the last-known tip and everything that was said.
This is what the "Closed" list on GitHub is for, and it works here without the branch having to be promoted into a PR first to earn a persistent record.
Archiving#
Archive branch on the branch page closes a branch without merging it — the "we're not going ahead with this" action, preserved rather than deleted. Unarchive puts it back. Member-only, like every other mutation on the page.
One caveat, stated honestly#
Squash a branch in by hand and it shows as deleted, not merged. Merge detection asks git whether the branch tip is an ancestor of the default tip, and squashing rewrites the commit so it isn't one. The record is intact and the branch page still works — the chip is just wrong. A merge-marker in the prompt ledger is the intended fix and hasn't landed. The Merge button never squashes, so this only bites when you do the merge yourself.
Ordinary merges and fast-forwards are detected correctly.
Why "pull requests" isn't just missing#
The term is deliberately reserved. A pull request in the original sense is for a contribution from someone outside the repo — a fork, a stranger, someone with no write access. That flow needs its own design (what a stranger may see, how their branch reaches you, what happens to their key on an encrypted repo) and does not exist yet.
Reusing the phrase for "a branch belonging to someone who already has write access" is what GitHub did, and it means there's no word left for the actual case. So amadan keeps the words apart: branches now, pull requests when third-party contribution is genuinely built.
Practical differences to expect#
- Nothing to open. Push the branch, and it's reviewable. There is no state where work is invisible because nobody clicked "create PR".
- Push a description with the branch. Nothing prompts you the way the PR form does, so the habit has to replace the prompt.
- Review by branch, not by PR number. Links are
/{ns}/{repo}/-/branch/{name}/review. - No required reviewers, no merge queue, no branch protection. The CI gate above is the only thing that can refuse a merge, and it refuses the button rather than the push. If your workflow depends on enforcement, amadan will not enforce it for you today.