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
This commit is contained in:
parent
ad47664e01
commit
a669cd96b6
17 changed files with 1156 additions and 50 deletions
|
|
@ -437,6 +437,10 @@ let
|
|||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/data/${classifierForgeTokenLeaf}" {
|
||||
capabilities = ["create", "read", "update"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/data/${swarmAppserviceTokenLeaf}" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
|
@ -567,6 +571,12 @@ let
|
|||
# wrote in memory); the CI runner's fetch unit is its one reader.
|
||||
ciRunnerTokenLeaf = "swarm/services/ci-runner/registration-token";
|
||||
|
||||
# The review classifier's forge token, the nix half of
|
||||
# `swarm_secret_client::review_classifier::forge_token_path`. The controller
|
||||
# mints it, reads it back before deciding whether to re-mint, and posts the
|
||||
# classifier's reviews with it; no other principal's policy reaches it.
|
||||
classifierForgeTokenLeaf = "swarm/services/review-classifier/forge/token";
|
||||
|
||||
# The UI's OIDC client secret. The publisher writes it; the granter reads it
|
||||
# into the `oidc` auth method's config, which is the only copy bao uses.
|
||||
baoUiClientLeaf = "swarm/services/${cfg.ui.oidc.clientId}/oidc/client";
|
||||
|
|
|
|||
Loading…
Reference in a new issue