Coordinate coding agents with nothing but GitHub.
Rallypoint installs eight roles, a label state machine and an atomic claim into your repository. Agents never message each other: they read and write issues, branches, labels and pull requests — and no agent approves its own work.
npx rallypoint@latest add loopRead the docs MIT · agent-agnostic
#142 Retry failed webhook deliveries
Illustrative run · real commands
Planner planner-2b80Step 1 of 7
gh issue create --title "Retry failed webhook deliveries" --label prio:p1No hold label, no assignee: the issue is claimable the moment it is filed. There is no readiness label to forget.
One claim per issue, decided by GitHub.
Assignment is not a lock. Before a worker touches an issue, claim.mjs creates a reservation ref. GitHub creates a ref exactly once — so when two sessions reach for the same issue, one gets it and the other moves on.
claim.mjs reserves before it mutates, and skips a contended issue without touching it.Labels are the state machine.
There is no side-channel database. An issue’s labels say whether it can be claimed, who holds it, and what it is waiting on; a pull request’s labels carry the verdict. Every agent reads the same board.
Issue
Claimable
Open, no assignee, no hold label. Filing an issue makes it claimable.
status:claimed
Set by
claim.mjsonly after the reservation ref exists.release-claim.mjsreturns it to the pool.Closed
Closes #Nlands, the claim is released.Refs #Nreleases it and leaves the issue open.
Held out of the pool
- status:blockedOnly with a
Blocked-By: #41trailer; clears itself when the last blocker closes. - status:deferredA deliberate hold that will not clear on its own.
- needs:humanAn owner decision. No automated writer may remove it.
Pull request
Ready for review
One branch,
agent/<issue>-<slug>, body saysCloses #N.status:changes-requested
The fixer pushes to the same branch; the head moves, the verdict stops binding, review runs again.
review:approved
Applied only by
review.mjs, bound to one head SHA, never from the author’s own session.Merged
The merger checks CI itself and that the head has not moved since the verdict.
Flagged, never hidden
- merged:unreviewedMerged without an approve verdict at its head.
| Label | Config key | On | Meaning |
|---|---|---|---|
| status:claimed | claimed | issue | Reserved by one worker right now. |
| status:blocked | blocked | issue | Waiting on another issue, named in a Blocked-By: trailer. |
| status:deferred | deferred | issue | A deliberate hold that will not clear on its own. |
| needs:human | human | issue or PR | Requires an owner decision or a protected action. |
| review:approved | approved | pull request | Reviewer verdict on a pull request, bound to its head SHA. |
| status:changes-requested | changesRequested | pull request | A reviewer asked for changes and they are outstanding. |
| merged:unreviewed | mergedUnreviewed | pull request | Merged without an approve verdict at its head. |
| prio:p1 | prio:p0 … prio:p9 | issue | Priority. claim.mjs orders the claimable pool by this number and nothing else. |
Eight roles. None approves its own work.
Every session adopts exactly one role and works inside its boundary. Each role is one plain file under .rallypoint/roles/, so prompting an agent into it is one sentence.
| Role | Claims issues | Reviews | Responsibility | Contract |
|---|---|---|---|---|
| Orchestrator | No | No | Reads repository state and recommends what to run next. | Contract |
| Planner | No | No | Keeps an ordered, well-scoped backlog. | Contract |
| Worker | Exactly one | Never own work | Ships one issue as one pull request. | Contract |
| Reviewer | No | Yes | Judges the current revision against the issue and repository rules. | Contract |
| Tester | Its own filed gap | No | Finds the weakest coverage area and closes one gap. | Contract |
| Fixer | No | No | Addresses review feedback on an existing pull request branch. | Contract |
| Janitor | No | No | Repairs GitHub coordination state: stale claims, orphaned refs, leases. | Contract |
| Merger | No | No | Verifies CI and the verdict, merges, and reconciles the claim. | Contract |
UTON OS was built through this loop.
A studio booking platform with payments, delivered by agents in Claude Code, Codex and OpenCode with GitHub as the only source of truth: 1,328 pull requests opened and 1,256 merged in eight weeks. Payments, credentials and auth stayed on human-only approval paths.
Two commands. Then it is your code.
Rallypoint’s zero-dependency CLI reads its own checksummed manifest, refuses conflicting writes, and leaves an existing AGENTS.md untouched.
1 Write the loop into your repository
npx rallypoint@latest add loopWrites the loop with Rallypoint’s own conflict-safe CLI. Add the dry-run flag to plan without writing.
2 Bring GitHub up to date
npx rallypoint@latest initNeeds an authenticated gh. Syncs the integration branch to your default branch, creates the labels the loop reads and writes, and reports — without changing — branch protection.
What lands in the repository
AGENTS.mdAGENTIC_LOOP.mddocs/AGENT_LOOP.md.rallypoint/LICENSE.rallypoint/config.json.rallypoint/roles/orchestrator.md.rallypoint/roles/planner.md.rallypoint/roles/worker.md.rallypoint/roles/reviewer.md.rallypoint/roles/tester.md.rallypoint/roles/fixer.md.rallypoint/roles/janitor.md.rallypoint/roles/merger.md.rallypoint/scripts/claim.mjs.rallypoint/scripts/review.mjs.rallypoint/scripts/report.mjs.rallypoint/scripts/janitor-pass.mjs
…and the rest of the scripts. view loop lists every file with its checksum.
- Plain text, fully yours to edit
- Every installed file is plain text — roles, config, scripts. Edit it, delete it, rewrite it. There is no proprietary format to work around.
- Downloaded once, not rented
- “add loop” writes real files into your repository once. From that moment they are yours to change, not a subscription you keep paying for.
- Runs where your code runs
- Every role runs inside your repository, your CI, your credentials. Nothing calls home, because there is no Rallypoint server to call.
- MIT, permanently
- What gets installed is MIT-licensed, permanently and non-exclusively. If Rallypoint disappeared tomorrow, what is already in your repository keeps working.