Files
gitea-review-bot/ROADMAP.md
T
Keysat 7ac1267dd0 Watch a repo for commits pushed by anyone but me
The bot only ever saw pull requests, so a collaborator with write access
who pushes straight to master was invisible: 18 of the last 50 commits on
ten31-brand's master arrived that way, unreviewed and unannounced.

Opt-in per repo (watch_pushes + [gitea] my_emails). Each poll cycle it
pages commits newer than a stored cursor across every branch except ones
with an open PR, keeps the commits whose git email isn't mine, posts a
notice naming author, branch, commits and files, records them, and only
then runs a claude -p assessment threaded under it. Identity comes from
the git email because these commits aren't linked to Gitea accounts.

The notice is deterministic Gitea data and the "outside the expected
area" flag is computed from globs, so the thing you actually need never
depends on a model call. Recording before the assessment is what stops a
crash in those minutes from reposting the whole notice.

Both prompts now put every attacker-authored field — titles, commit
subjects, filenames, the diff — inside a nonce-tagged fence, so a forged
terminator can't reach the instruction region.

Folds in the ROADMAP item to bound two unbounded awaits and exit if the
poll task dies, and adds the repo's first test: the watch policy against
a real-shaped Gitea fixture, with 17 mutations confirmed to fail it.
2026-08-21 10:46:03 -05:00

3.0 KiB

gitea-review-bot — ROADMAP

Phases beyond the first milestone (threaded single-flow review + merge/reject/deploy; see AGENTS.md ## Current state).

Phase 3 — Multi-repo at scale

  • Onboard ≥3 repos to their own rooms; confirm independent polling, no cross-talk. Exit: three repos reviewed from three rooms in one run. (adjudicated 2026-07-18: verify — needs no new code; rooms are already independent (per-room heads/threads/agents are namespaced, merge-confirm state is keyed by room+PR). Check plan, when a real 2nd/3rd repo is onboarded: watch one poll cycle in docker compose logs -f. Note the exit criterion is mis-stated — reviews run serially (one async task walks the rooms in turn), so "no interleaving" is trivially satisfied; the thing actually worth watching at 3+ repos is a long review head-of-line-blocking the next room's poll, i.e. the latency problem the deferred poll→webhook item anticipates.)
  • Status 2026-08-18: 2 of 3 onboarded — ten31-site and ten31-brand. Mapping a room mid-run needed no restart. The head-of-line-blocking watch above is now possible but still unobserved: it needs open PRs in both rooms at the same time.

Fold-ins — do opportunistically, never a session of their own

  • Bound the two unbounded awaits and die if the poll task dies. Done 2026-08-21, folded into the push-watch change: ssh_run's post-kill proc.wait() and say()'s client.room_send are both wait_for-bounded, and a poll-task death now os._exit(1)s so restart: unless-stopped brings the bot back instead of leaving it synced but reviewing nothing.

Next up

  • Restrict what the assessment/review session may do. A PR diff and a pushed commit are both written by someone else, and they reach claude -p through matrix-bridge's ask-claude.sh, which exports the owner's OAuth token and runs in the owner's live checkout with the default tool policy. Both prompts now fence the diff as untrusted data, which is the cheap half; the real fix is an explicit read-only tool policy (--allowedTools Read,Grep,Glob,Task) on that run. It needs a matrix-bridge change (a MB_CLAUDE_TOOLS env passthrough alongside the existing MB_CLAUDE_MODEL/MB_CLAUDE_EFFORT), so it is a two-repo change and affects the PR review path too. (raised by the 2026-08-21 reviewer pass on the push watch.)

Deferred / non-goals

  • Not a Claude-session bot (that's matrix-bridge); not Maubot (revisit at ~6+ bots or web-UI mgmt); no GitHub/non-Gitea; no Gitea account/permission management; E2EE deferred (private LAN transport).
  • A shared "bot kit" library (extract the common matrix-nio + SSH plumbing across the three bots) once duplication bites — the lighter step before ever considering Maubot.
  • Poll → webhook upgrade if 60s latency ever matters.
  • Ops/dashboard tile lives in spark-control, not here — its Bots tab has shipped a gitea-review-bot tile since v0.28.0 (status badge, Update, Start/Restart/Stop, View logs), confirmed live.