The pull requests card gets a diff column, the lines a PR adds and removes
(`+120 −8`), sortable on the total. The controller takes the counts from the
forge's pull request list, so no call is added. The column that said "has all
approvals" is now headed "approved".
The reports tab gets a "pull requests" card under the issue report. It lists
the open PRs of every repo, or of one picked in a repo select, with the
columns a reviewer or merger filters on: author, labels, requested
reviewers, base branch, WIP (the forge's draft flag), approvals against the
base branch's protection rule, has all approvals, conflicts, protected base
and CI. Every column sorts, the small-set columns filter by picking values,
and the browser keeps the filters and the repo. No filter applies at first.
swarm-controller resolves each row so the page makes no calls of its own:
GET /api/pr-report and GET /api/repos/{org}/{repo}/pr-report. The required
approvals come from the first matching branch protection rule (an
unprotected base asks for none); an approval counts when it is the
reviewer's latest decision, on the current head, neither stale nor
dismissed and official.
A free-text table cell gets a minimum width, so a table with many columns
scrolls sideways instead of wrapping a title to a word a line.
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.
a re-created cache signs with a new key; the fact was only created once, so
every hive then rejected the swarm's closures. the cache's grant gains update
on that one leaf, and a store that refuses it leaves the key as it was.
Closes#6181
A meta build whose attic push failed (attic or its token not up yet) is
recorded with cached false and the deploy goes ahead. Nothing sent that
build again until internal/meta moved, so the create for that agent
failed on every hive and a rebuild was silently never pending.
The controller's cache-miss pass now also takes a record from the head
with cached false: it sends the same build without asking the cache, with
the pass's existing backoff (30 min doubling to 12 h), and rewrites the
record with cached true once the push lands, under the same
compare-and-set guard as a path change. The push.rs module doc no longer
claims the next build pushes again.
Mixed versions: controller-only, same wire type and builder request. An
old controller leaves an uncached record as before; a builder needs no
change.
Closes#6173
Reads GET /api/agents/{name}/term/stream over the controller socket or the
gateway and prints one line per row. The gateway path uses a client without
the total-request timeout so the stream isn't cut after 30 seconds.
Closes#6160
Both pollers wait about ten minutes for the agent's token, then exit 0.
Under Restart=on-failure that exit is final, and nothing started them
again, so a token minted or placed after the window left the agent
without notifications until its container restarted.
Add a path unit per poller with PathChanged on the token file(s) the
poller reads, the shape forge-avatar-sync already uses. A path unit
starts its service only when it is not running, so a poller that found
its token is untouched. The github path unit is gated on
github.enable like its service.
Container-side: it ships with the agent's next rebuild, and an agent on
an older rev keeps the old behaviour.
Closes#6179
Wraps PUT /api/hives/{hive}/agents/{agent}/state, the route the swarm UI's
state menu uses. States come from swarm_wire::wanted::AgentState; destroyed
needs --yes.
Closes#6159
JobqGraph takes an optional loading element, so the dashboard keeps its text
and the swarm UI's jobs tab passes a placeholder built from the graph's own
node and row classes: a root with two children and a second root, with the
real indent and rail.
The form's credential choice now starts on 'log in with a password', listed
first, with a note that the swarm's own login gives the account a device of
its own. Choosing 'paste a token' shows a warning: a token from Element or
another client belongs to a device that is already logged in, so the agent
cannot use its encryption keys and the account will not decrypt encrypted
rooms.
The broadcast grid showed nothing while the agents loaded, and the egress
card a 'loading the … domains' line. They now show grey placeholders in the
shape of what is coming: six agent chips with the real chip's height (160 px,
measured), and three domain rows with their remove buttons.
The label 'message <agent>' is the input's placeholder (the label stays for
screen readers). The send button shows a spinner over its label while the
request is pending and keeps its width, and the 'sent' line is gone: the box
empties when the message is held. Spinner is a component of its own now, used
by the button and the refresh picker.
The schedules card, the notification router card (flows and recent
deliveries) and the flow editor showed a bare 'loading…' line. They now show
grey placeholders in the layout of what is coming: schedule cards with the
real card's row heights, flow cards with a block for the graph, the
deliveries table's header over blank rows, and lines for the editor.
boundary.md keeps the model, the design rule, why network isolation
matters and host admin socket access; the hive-priv socket activation and
the per-agent socket directory move to 4-implementation/trust-boundary.
security.md keeps the agent trust model and the path-name rule; the nix
builds mode with its threat model, and the hive-c0re privilege separation,
move to their own pages there. Headings and text move as they were, with
one level shaved off the heading depth. Links, code and nix pointers, and
the docs index follow the moves.
Every docs directory moves under 1-getting-started, 2-handbook,
4-implementation or 5-project; the options reference (section 3) comes from
the website and has no directory here. trust-boundary stays whole under the
handbook for now. web-ui, swarm and tools split between handbook and
implementation, and the command-line references move to
2-handbook/reference. Links, path references in code and nix, and the docs
index follow the moves; no page content changes.
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.
BadgeSkeleton is the twin of Badge: the real Badge frame, as tall as an
interactive one (the settings values are buttons), with a placeholder for its
value. Permissions, resource caps, internet and allowed domains use it in place of
their "loading…" text, the details popover shows lines of text, and the
AGENTS.md editor a block, in place of theirs. SkeletonLines is a few stacked
lines for such blocks.
nspawn idmaps the store on erofs, which the VM test's store uses; the
allowlist from the store check refused it and failed the namespaced-agent
subtest in vm-nightly #7084. vm-nightly #7030 ran the same agent on the
same erofs store green. The magic is EROFS_SUPER_MAGIC_V1 from the
kernel's linux/magic.h; libc has no constant.
Refs #5888
memory_max and cpu_quota are checked against the shapes systemd takes
before write_resource_limits makes any file. validate_bind_path also
refuses whitespace, control bytes, backslash, dollar and backtick, which
the start script expands unquoted in EXTRA_NSPAWN_FLAGS. bridge must be
an interface name and gateway_ip an IPv4 literal. Each refusal names its
field.
Closes#6086
The webhook secret slot is filled in the background, on the forge token's
capped unbounded backoff, when the store can't answer at start. The hook
registration waits for the secret and retries on the same backoff instead
of giving up after five tries.
Closes#6101
The page's composer (its input, slash commands and completion), POST /send in
hive-agent, the OperatorMsg request of the agent socket and its handler in
hive-c0re, and the broker-error helper only the send route used are deleted:
writing to an agent is the swarm UI's terminal. cancel turn, new session and
log out stay in the state badge's menu; POST /api/compact stays, with nothing
on the page calling it. The request-line limit keeps its size, and its comment
says it is a generous bound now. The docs describe the actions in place of the
footer and the prompt.