add PR state machine: labels, transitions, assignment rules, automated sweep
All checks were successful
check / check (push) Successful in 11s

This commit is contained in:
clawbot 2026-02-28 02:40:17 -08:00
parent e9e24638fd
commit 780b231c41

View File

@ -72,6 +72,121 @@ The issue tracker is the single source of truth for what needs doing, who's
doing it, and what's done. Everything else (PRs, branches, deployments) links
back to issues.
### PR State Machine
Once a PR exists, it enters a finite state machine tracked by Gitea labels and
issue assignments. Labels represent the current state; the assignment field
represents who's responsible for the next action.
#### States (Gitea Labels)
| Label | Color | Meaning |
| -------------- | ------ | ------------------------------------------------- |
| `needs-rebase` | red | PR has merge conflicts or is behind main |
| `needs-checks` | orange | `make check` does not pass cleanly |
| `needs-review` | yellow | Code review not yet done |
| `needs-rework` | purple | Code review found issues that need fixing |
| `merge-ready` | green | All checks pass, reviewed, rebased, conflict-free |
#### Transitions
```
New PR created
[needs-rebase] ──rebase onto main──▶ [needs-checks]
▲ │
│ run make check
│ (main updated, │
│ conflicts) ┌─────────────┴──────────────┐
│ │ │
│ passes fails
│ │ │
│ ▼ ▼
│ [needs-review] [needs-checks]
│ │ (fix code, re-run)
│ code review
│ │
│ ┌─────────┴──────────┐
│ │ │
│ approved issues found
│ │ │
│ ▼ ▼
│ [merge-ready] [needs-rework]
│ │ │
│ assign human fix issues
│ │
│ ▼
└───────────────────────────── [needs-rebase]
(restart cycle)
```
The cycle can repeat multiple times: rebase → check → review → rework → rebase →
check → review → rework → ... until the PR is clean. Each iteration typically
addresses a smaller set of issues until everything converges.
#### Assignment Rules
- **PR in any state except `merge-ready`** → assigned to the agent. It's the
agent's job to drive it forward through the state machine.
- **PR reaches `merge-ready`** → assigned to the human. This is the ONLY time a
PR should land in the human's queue.
- **Human requests changes during review** → PR moves back to `needs-rework`,
reassigned to agent.
This means the human's PR inbox contains only PRs that are genuinely ready to
merge — no half-finished work, no failing CI, no merge conflicts. Everything
else is the agent's problem.
#### The Loop in Practice
A typical PR might go through this cycle:
1. Agent creates PR, labels `needs-rebase`
2. Agent rebases onto main → labels `needs-checks`
3. Agent runs `make check` — lint fails → fixes lint, pushes → back to
`needs-rebase` (new commit)
4. Agent rebases → `needs-checks` → runs checks → passes → `needs-review`
5. Agent does code review — finds a missing error check → `needs-rework`
6. Agent fixes the error check, pushes → `needs-rebase`
7. Agent rebases → `needs-checks` → passes → `needs-review`
8. Agent reviews — looks good → `merge-ready`
9. Agent assigns to human
10. Human reviews, merges
Steps 1-9 happen without human involvement. The human sees a clean, reviewed,
passing PR ready for a final look.
#### Automated Sweep
A periodic cron job (every 4 hours) scans all open PRs across all repos:
- **No label** → classify into the correct state
- **`needs-rebase`** → spawn agent to rebase
- **`needs-checks`** → spawn agent to run checks and fix failures
- **`needs-review`** → spawn agent to do code review
- **`needs-rework`** → spawn agent to fix review feedback
- **`merge-ready`** → verify still true (main may have updated since), ensure
assigned to human
This catches PRs that fell through the cracks — an agent session that timed out
mid-rework, a rebase that became necessary when main moved forward, etc.
#### Why Labels + Assignments
You could track PR state in a file, a database, or just in the agent's memory.
Labels and assignments are better because:
- **Visible in the Gitea UI.** Anyone can glance at the PR list and see what
state each PR is in without reading comments.
- **Queryable via API.** "Show me all PRs that need review" is a single API call
with a label filter.
- **Durable.** Labels survive agent restarts, session timeouts, and context
loss. The state is in Gitea, not in the agent's head.
- **Human-readable.** Color-coded labels in a PR list give an instant dashboard:
lots of red = rebase debt, lots of orange = CI problems, lots of green = ready
for review.
## Real-Time Activity Feed: Gitea → Mattermost
Every repo has a Gitea webhook that sends all activity (pushes, PRs, issues,