Watch
0
0
Fork
You've already forked hyperhive
0
Commit graph hyperhive/docs/swarm/review-classifier.md
Author SHA1 Message Date
iris
9a4059e130 swarm-ui, swarm-controller: the review try-out's repo and PR fields offer the repos and PRs to pick
Two read-only routes feed them: GET /api/pulls/repos lists the repos with an
open pull request, and GET /api/pulls?repo=owner/name lists a repo's open
pull requests, highest number first. The page offers the lists through the
browser's own suggestion list and keeps both fields free text, since a run
also works on a merged or closed PR.
2026-10-12 19:05:37 +02:00
atlas
60ea7fdc04 swarm-controller: harden the review classifier's real reviews
Follow-ups from the review of #5142.

A `Done` answer with fewer or more rows than the classifications sent, or
none, now posts the no-verdict comment instead of the classifier's overall
verdict, so a short answer can't approve.

Requests are accepted per repo, PR and head into a set bounded at the two
running plus eight waiting. A request for a key already running or waiting
starts nothing and logs at info; a request with every place taken starts no
run and posts a no-verdict comment saying so. Before, every delivery spawned
a task waiting on the semaphore, so toggling the review request queued one
paid run per toggle.

Table cells get a zero-width space after `#`, `!`, `://` and `www.`, so a
model's reason can't render an issue or PR reference or a bare URL as a link.

The secret publisher's policy denies the classifier's forge token leaf, the
way #5139 denied Grafana's admin password, with a module-eval-bao-grants arm
pinning it. The controller posts reviews with whatever token is there, so a
publisher write picked the account reviews come from.

Closes #5143, part of #5096.
2026-10-12 18:38:05 +02:00
atlas
a669cd96b6 swarm-controller: post the review classifier's verdict on a review request
Requesting the forge account `review-classifier` as a reviewer now runs the
repo's rules against the PR and posts the result as that account's review,
on the head commit the run read. A push starts no run; only a fresh review
request does.

- An instance-wide `pull_request_review_request` system hook delivers to
  `/webhook/forge/review-request`. A request for any other reviewer, or a
  removed request, does nothing.
- The controller reads the PR, loads the rules with the same reader as
  `GET /api/review-classifier/rules`, sends one request on the try-out
  subject, and posts APPROVED or REQUEST_CHANGES with the table as the body.
- With no clean verdict (PR or rules don't load, the run fails, or any
  classification has no answer) it posts a COMMENT saying why, never an
  approval. The event is one function, `no_clean_verdict_event`.
- Table cells are flattened, markup-escaped, and every `@` gets a
  zero-width space, so a model's reason can't break the table or mention
  anyone.
- At most two requested reviews run at once; the rest wait in memory.
- The account is minted the way hive accounts are: a five-minute pass
  queues a `MintClassifierForgeToken` node when the token at
  `swarm/services/review-classifier/forge/token` is missing or stale. The
  token is `write:repository`. The controller's bao policy gains that leaf
  (create/read/update), pinned in module-eval bao-grants. The classifier
  never sees the token.

The account gets no repo access automatically; a repo admin adds it by
hand. A re-request retires the account's earlier review: Forgejo clears
`official` on a reviewer's earlier reviews when it is requested again
(models/issues/review.go AddReviewRequest, v16.0.5), and approvals and
rejection blocks count official reviews only.

Refs #5137
2026-10-12 16:11:50 +02:00
atlas
2b1573c2ba swarm-controller: read review rules at a literal nested path
forgejo-api escapes the whole file path of a raw-file request, so the
rules file went out as `raw/.hyperhive%2Freview-classifier.yml` and
reached the forge only if every proxy and router in between decoded the
`%2F`. The controller now sends that one request itself: `raw_file_url`
escapes each path segment on its own and joins them with `/`, and
`forge::Client` holds a second HTTP client with the same token for it.

A 404 from the default-branch lookup now means "no commit on the
default branch", like an empty repo, instead of falling through to the
route's "no repo" answer. Only the repo lookup's 404 still means the
repo doesn't exist.

Tests cover the URL shape, the reads against a loopback stub forge
that serves only the literal path, the branch 404, 503 with no forge
access, 503 at the forge deadline on a paused clock, and a bad
polarity value.

Part of #5096.
2026-10-12 14:54:59 +02:00
atlas
16c7c249ef swarm-controller: read a repo's review rules from its default branch
`GET /api/review-classifier/rules?repo=owner/name` reads
`.hyperhive/review-classifier.yml` or `.json` from the repo's default
branch with the controller's forge token, on every request, and answers
the classifications in the try-out POST's shape, plus the file, the
branch and the commit it was read at. The swarm UI's try-out page loads
them into its editor (#5134).

The file is one `classifications` list of the try-out's `Classification`.
A missing file, both files, a parse error, any unknown key, an empty list
or more than ten entries is a problem+json error, never a pass. The
checks the POST makes on its classifications move into one function both
paths call.

The doc names the file and its schema, replacing the placeholders, and
documents the route.

Part of #5096.
2026-10-12 14:54:59 +02:00
atlas
6c9cb66dce docs: the review classifier's try-out service, its key and its subject
- review-classifier.md: claude runs spawn through hive-claude directly
  with no tools and no session (hive-runtime holds only TurnStop); the
  answer's fields, the 500-character reason cap and what a failure does;
  how the try-out page reaches the classifier; the settled parts of the
  open list (API key path, try-out subject, --tools "" on claude).
  The banner stays.
- services.md: a Review classifier section with the two operator steps.
- secrets.md, credentials.md: the classifier's leaf and the key row.
- network.md: the container's row. CLAUDE.md: the crate.
2026-10-12 13:11:21 +02:00
atlas
46e9966e17 docs/review-classifier: cost comes from OTEL labels, not the swarm UI 2026-10-10 19:30:25 +02:00
atlas
00ce00f33d docs: narrow the review-classifier runtime refactor to the per-turn seam 2026-10-10 18:56:30 +02:00
atlas
dcd005623e docs: make review classifier page generic over swarms
Drop the swarm-specific reviewer agent name and the hyperhive-repo
approval count from the architecture page and its index line.
2026-10-10 18:54:02 +02:00
atlas
c0af8d1fd3 docs: review classifier architecture (planned)
Add docs/swarm/review-classifier.md, the high-level architecture of the
planned PR review classifier pipeline, written as the full target shape
under a "planned, not implemented yet" banner. Link it from docs/README.md
and the docs/swarm/README.md piece list.

The page reflects the epic description and the operator's answers in the
epic thread; points still open are listed in its "Still open" section.
The banner names the epic by title rather than by number because the
tracker-tag lint rejects issue references in tracked files.
2026-10-10 18:53:41 +02:00