An answer that fails to validate is asked for a second time, for that classification only, with a reminder to reply with the JSON object alone. The second ask comes out of the classification's CLASSIFICATION_DEADLINE: it gets what the first ask left, and is skipped when less than 20 seconds remain, so RUN_DEADLINE's bound still holds. A failed ask (runtime error, timeout) is not repeated. If the second answer does not validate either, the row has no answer, as before. Model::ask takes the deadline for the ask; the ACP runtime no longer holds its own. The parser also takes the first fenced block of a reply that has prose around the fence; prose around a bare object is still rejected.
36 lines
2 KiB
Markdown
36 lines
2 KiB
Markdown
# swarm-review-classifier
|
|
|
|
The review classifier's try-out service, in the `swarm-review-classifier`
|
|
container on the host that sets `deploy.review-classifier.enable`. The
|
|
design is [`docs/swarm/review-classifier.md`](../docs/swarm/review-classifier.md).
|
|
|
|
swarm-controller reads a PR (its head commit, its commits and its diff) and
|
|
sends it, with the operator's classifications, as a request on the queue.
|
|
This service asks a small model one classification at a time and answers
|
|
with the result table and the overall verdict. It writes nothing to the
|
|
forge and holds no forge credential.
|
|
|
|
## What a run is
|
|
|
|
- The shared context first: a system prompt, the PR's commits with their full
|
|
messages, and the diff with lockfiles collapsed as `hive-forge diff` does.
|
|
Every classification's prompt starts with the same bytes, and `claude` gets
|
|
that part as a content block of its own, with a cache breakpoint at its end.
|
|
- One `claude --print` per classification, with no session, no tools
|
|
(`--tools ""`), no MCP server, its own empty directory and
|
|
`ANTHROPIC_API_KEY` in its environment only.
|
|
- An answer is a JSON object with a verdict, a certainty and a reason; the
|
|
prompt asks for a reason under 350 characters, and the classifier truncates one over the 500 cap to 499 plus `…`. A failed run, a
|
|
timeout or an answer that doesn't validate leaves that row without a verdict, and it doesn't count.
|
|
An answer that doesn't validate is asked for once more first, with a
|
|
reminder to reply with the JSON object alone, within the same three minutes.
|
|
- A run with no API key, or with no classification answered, fails as a
|
|
whole: the caller sees an error, never a verdict.
|
|
|
|
## Credentials
|
|
|
|
The container holds one credential: its own store certificate, which nspawn
|
|
hands in at start without a copy on disk. With it the service
|
|
reads its queue client secret at start and the API key at every run, so a key
|
|
written or removed in the store takes effect on the next run. Its store role
|
|
reads exactly those two paths.
|