GitHub
Point a repository at Félagi and the work people do in GitHub arrives on the issue it belongs to — whoever did it, agent or person.
Two halves, and the second is optional. Listening needs no credentials at all: GitHub posts, Félagi reads. Replying needs a GitHub App, and adds a check and a comment to each pull request.
Connecting
Administration → GitHub → Connect. Félagi gives you two things:
| Payload URL | Where GitHub posts. Safe to be seen — it says where, not who. |
| Secret | Shown once. GitHub signs every delivery with it. |
In GitHub, on the repository: Settings → Webhooks → Add webhook. Paste both, set
content type to application/json, and choose Pull requests and Pushes.
The secret is shown on the screen that made it and not again. Leaving it on a page anybody can revisit is the same as not having one — if you lose it, press New secret and paste the new one over. The URL stays the same, and GitHub is refused until you do, which is the intended noise: a rotation nobody notices is a rotation that did not happen.
One hook per workspace. A shared secret could not be rotated for one customer without rotating it for everybody, and it would make two organisations indistinguishable to us.
Naming the issue
Put the identifier in the branch name:
INF-12-fix-the-redirect-loop
feature/INF-12-fix-the-redirect-loop
Félagi looks in the branch first, then the pull request title, then its body, and takes the first issue it finds. The branch wins on purpose: it is chosen when the work starts, by the person doing it, and it does not get rewritten later the way a title does — and a title often mentions a neighbouring issue in passing.
An identifier needs its separator. INF-12 is an issue; INF12 is refused, because a
prefix may contain digits (PRE2 is legal), so PRE214 could be PRE-214 or PRE2-14
and nothing in the string decides. A prefix this workspace does not answer to is refused
rather than ignored, so XYZ-1 never quietly finds issue 1.
What happens
A branch is cut
The issue records the branch and starts. There is no "branch created" event in
GitHub — it arrives as a push with created set, and it is the earliest honest signal
that somebody has begun, usually hours before a pull request exists.
It lands on whatever your workspace calls started: rename in progress to Building and
you get Building.
It never moves an issue backwards. A follow-up branch on something already in review changes nothing, and neither does an ordinary push — a commit-by-commit log belongs in GitHub. Deleting the branch takes it off the issue, because a link to a branch that is gone is a link to a 404.
Tags are pushes too, and are ignored. A tag named after an issue is not somebody starting.
A pull request opens, merges or closes
The issue shows the pull request and follows its state: draft, open, merged, closed.
GitHub reports a merge and an abandonment identically — state: closed for both — so
Félagi reads the merged flag to tell them apart.
An issue that is in review finishes when its pull request merges, and goes back to in progress if the pull request is closed unmerged. It does not reach into work that is in progress, on hold, or already finished by somebody: this closes a handover, nothing more.
The timeline says what happened and names the GitHub account that did it — as what it is, a name GitHub gave us. It is not credited as a colleague, because guessing which person a login belongs to would name the wrong one sooner or later.
Replying (optional)
With a GitHub App installed on the repository, Félagi adds to each pull request:
- a check naming the issue, its title and its status
- one comment with the same, kept current
The same sentence twice, for two kinds of reader: the check for whoever is scanning a list of pull requests, the comment for whoever is reading the conversation.
Making the app
GitHub → Settings → Developer settings → GitHub Apps → New GitHub App.
| Setting | Value |
|---|---|
| Permissions | Checks: read & write, Pull requests: read & write |
| Webhook | Off — Félagi already has one |
Generate a private key, install the app on the repositories you want, then open the installation in GitHub's settings: the installation id is the number at the end of that URL.
Paste the App ID, the installation id and the .pem into Administration → GitHub →
Reporting back. The key is stored encrypted and never shown again.
Save and verify asks GitHub whether the credentials work before the page says they do. Saving and reporting success is how a settings screen lies — the alternative is a green tick here and silence on every pull request afterwards.
Why an app and not a token
A personal access token would have been simpler and worse. It carries one colleague's entire account, it stops working the day they leave, and every comment Félagi wrote would arrive under their name. An app is nobody in particular, holds exactly the two permissions above, and its tokens expire in an hour.
The check is always neutral
It reports; it does not judge. A green tick would claim the pull request passed something, and a red cross would block somebody's merge over a link — which is not Félagi's place. It cannot be made a required check, and is not meant to be.
Is it working?
The connection says which of three things is true, because two of them look identical from GitHub's side:
| Badge | Means |
|---|---|
| never called | GitHub has not posted once. Check the URL and the events. |
| refusing | GitHub is posting and being turned away. Almost always the secret — a copied space at either end is enough. |
| listening | Deliveries arriving and accepted. |
And separately, for the replying half: listening only, replying, or cannot reply. A connection that can hear GitHub and cannot answer it is a third state, and without saying so it looks exactly like health.
The page also shows what arrived last and when. An event Félagi has no opinion about is recorded as having arrived and then ignored — so "GitHub is calling and nothing happens" and "GitHub has never called" are never the same picture.
What it does not do
- Nothing is written to your code. Félagi never pushes, merges, labels, closes or reopens anything in GitHub.
- Reviews and comments stay in GitHub. They are not mirrored onto the issue.
- One issue per pull request. A pull request naming several attaches to the first.
- Only GitHub speaks GitHub. Any other forge can still report through the generic delivery hook — see Delivering work, which takes a URL and a state and nothing else.
Security
Félagi verifies X-Hub-Signature-256 over the raw bytes GitHub sent, using this
workspace's secret. A delivery that does not verify is refused with a 404 and written
down.
An unknown token is answered with 404 rather than 401, deliberately: a 401 confirms the address is real and only the credential is wrong, which is the one fact somebody probing a guessable URL is looking for.
The webhook endpoint is exempt from forgery protection — GitHub has no session and no token, and proves itself by signing the body instead.