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 doing it, and what's done. Everything else (PRs, branches, deployments) links
back to issues. 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 ## Real-Time Activity Feed: Gitea → Mattermost
Every repo has a Gitea webhook that sends all activity (pushes, PRs, issues, Every repo has a Gitea webhook that sends all activity (pushes, PRs, issues,