The classifier's Anthropic and ACP provider keys were written by hand in the
secret store's UI. The controller now stores them: GET
/api/review-classifier/keys says whether each is set and when it changed, and
PUT /api/review-classifier/keys/{runtime} writes one. No route answers a key.
The controller's store policy gains create and update on the two leaves with
no read of their values, and a metadata read for the set state. The swarm UI's
classifier settings card gets a key form beside the settings, saved apart
because it goes to the secret store.
failures_only (off by default, also for a stored document without it) makes the
review the classifier posts on a PR list just the rows that failed their rule,
or say that no check failed on an approval. A review with no clean verdict and
a try-out keep every row. The classifier settings form gets a checkbox for it.
The limit was a constant of ten in swarm-wire, so a repo with eleven rules
could not be reviewed and nothing short of a rebuild changed it. It is now
`max_classifications` in the classifier settings, beside
`max_concurrent_reviews`: 1 to 1000, ten until set, and a document stored
before the field decodes with the default. The classifier settings form in
the swarm UI gets a "rules per review" field, and the try-out's add button
stops at the saved limit instead of a hard-coded ten.
The controller checks a try-out, and a requested review's rules file, against
the setting where the run starts. The rules file itself may hold up to the
1000 the setting allows, so raising the limit needs no change to a repo.
A review whose rules exceed the limit posts a no-verdict comment saying so.
A run's reply deadline was a constant that covered ten classifications, a
minute plus three each. It is now computed from the run's own size, so a
bigger run waits as long as it needs and a default-sized one still waits 31
minutes. The classifier's answer window in the queue permissions covers the
biggest run the setting allows.
Classifier settings, the try-out target row and classification rows, and the
schedule cadence each wrote their own flex row with its own flex basis and
gap. FieldGrid is one grid with equal columns and one gap, FieldGridFull
spans a row, and the four forms use it, so a lone last field keeps its column
width and the columns share their edges in every row.
Hint, ActionRow, Toolbar, EmptyState and ExternalLink replace the muted
text, button row, refresh bar, empty line and _blank anchor that each page
restyled under its own class. ExpandableCard (with a loading twin) holds the
builds and recent-runs cards, which had identical head and body CSS. The
create form's raw checkbox becomes CheckboxField. The components page shows
each new piece.
The two groups of fields had different column counts, so their edges never met,
and the price labels carried their unit, which wrapped in a monospace font and
pushed those inputs below their neighbours. Every group is one CSS grid now. The
provider fields sit under a "provider" heading, with the URL and the model each
on a full row so their placeholders are not cut off, shorter price labels and
the unit said once under them.
The two review tabs, runs and try-out, are one: /review. It is a column of
three sections: try a classification and the classifier settings, each a
folded bar (the settings' bar says what they are now), then the recent runs,
always open. The settings had been pinned under the try-out form; they are now
a section of their own. A new Disclosure primitive is the folding bar, a
native details wearing the Panel's classes, so the folded and open sections
read as the same surface.
/review-runs and /review-tryout are gone, with no redirect.
The runtime list was exported but only its type was used, so the type is
now written out. The form's pure logic (draft, checks, request body,
change detection) gets tests under node's built-in runner, run by the
existing swarm-ui check.
The classifier settings page showed model and effort only, so the API-key
or ACP runtime could be switched only through a raw API call. It now has a
runtime select, and under ACP the provider's URL, model and prices. A PUT
carries the provider only on the ACP runtime, so the stored record stays
for a switch back. Closes#5249
A classifier settings panel under the try-out form reads and saves the model,
effort and how many requested reviews run at once through the settings route.
A save replaces all three; a refused one shows the route's reason and leaves
the form as typed. There is no API key field.