mara's steer on the issue, right as the previous commit's plan was
posted: the swarm-level term isn't a separate page, it's part of the
same pwa -- selecting an agent should show a small preview (no header,
no input) below the existing detail fields. That's the whole MVP for
this issue; the full terminal (+ sending input back to the agent) is
explicit follow-up scope.
AgentTermPage -> AgentTermPreview: drops the Panel wrapper, the
"terminal" nav badge + wouter route, and the back-link -- just the
inline preview, height-capped at 12em (@hive/shared/terminal.css's own
default is a much taller 72vh/60em, sized for a dedicated page rather
than a peek).
Moves the TermMsg rendering pipeline (Row.tsx, termMsg.ts, linkify.tsx,
markdown.ts) from @hive/agent into @hive/shared, so swarm-ui becomes a
second consumer of it instead of forking a copy -- CSS was already
shared (@hive/shared/terminal.css). marked+dompurify move from
@hive/agent's deps to @hive/shared's; swarm-ui picks them up
transitively, no new direct dep there.
New swarm-ui route /agents/:name/term (AgentTermPage), linked from
AgentsPage's detail panel via a "terminal" badge next to "link matrix
account". Consumes GET /api/agents/{name}/term/stream: unlike
@hive/agent's own useLiveStream (TermEnvelope-wrapped, history/backfill
dance), the swarm relay forwards one bare TermMsg per SSE event with no
envelope and no history endpoint -- useSwarmTermStream is a much
smaller hook for that shape (EventSource -> parse -> coalesce, nothing
to buffer/dedupe/backfill against).
Verified against a live SSE mock (screenshots in /agents/iris/state/screenshots/
3801-agents-detail-panel-terminal-badge.png and
3801-agent-term-page-live-rows.png -- real rows rendering through the
shared Row component, not just a build/typecheck pass).
autheliaCfg/forgeCfg/vmCfg/vlCfg were local re-exports of
hyperhiveCfg.swarm.<subpath> — a shape that hides the full option
path from grep, the same hazard #4356 fixed for the tls alias.
Removed the six let-bindings and spelled the full
hyperhiveCfg.swarm.<subpath>.<field> path at every use site instead.
None of the read fields (url, machine, hiveClientPrefix,
agentClientSuffix, domain, port) sit on the old side of a
mkRenamedOptionModule in deploy.nix, so inlining the alias's own
current path is correct as-is.
Refs #4363
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The previous commit left two delivery paths and a three-way gate:
`swarm-grafana-oidc-secret.service` copied authelia's minted plaintext
out of its host tree wherever the two were co-located,
`swarm-bao-grafana-oidc.service` read the same value from the swarm
secret store wherever they were not, and `ssoConfigured && (ssoLocal ||
haveClientIdentity)` decided whether Grafana got an OIDC block at all.
Delete the co-located path. The store reader is now THE delivery unit,
in every deployment — the publisher on authelia's host writes
`swarm/services/<id>/oidc/client` whether the reader is a network away
or in the container next door. The ruling behind it: the store exists so
a host holds ONE out-of-band secret, its client certificate, and reads
everything else with it. Skipping the store when the producer happens to
be local saves a round trip and costs a second delivery unit, a second
way for the file to be wrong, and a gate to choose between them.
The gate goes too, and both of its questions become assertions, scoped
to hosts that run Grafana:
- `swarm.authelia.url` must be set. `auth.disable_login_form` is
unconditional — Grafana ships an admin/admin account on a public
vhost — so dropping the OIDC block when the swarm names no IdP
produced a container with no SSO and no password box, silently. An
eval-time refusal naming the option is the only report that reaches
anyone, the shape swarm-nats.nix already uses for the same option.
- `deploy.bao.clientCertFile` / `clientKeyFile` must be set. This
replaces a warning that nothing reads back, and its message names both
options and where the leaf comes from.
Fixtures follow. `grafanaWithAuthelia` gains the cert pair, because a
co-located host is a store reader like any other. The old
`grafanaRemoteAutheliaNoIdentity` is kept rather than deleted, renamed
`grafanaNoIdentity`: the shape is still reachable, only its deliverable
changed from silence to a refusal, and an arm now reads that refusal
back. Its mirror `grafanaNoSso` covers the other assertion, each fixture
wrong in exactly one way so an arm can name which refusal fired. Every
positive keeps an explicit negative — the one-delivery-unit arm asserts
the deleted unit is absent in both topologies rather than merely that
the store reader is present.
Refs #4234
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Grafana's OIDC client secret only existed where authelia did. One
`ssoLocal` gate — `grafana.enable && authelia.enable` — decided the
client registration, the minted secret's delivery and the whole
`auth.generic_oauth` block, so a swarm whose authelia runs on another
host got Grafana with no SSO wiring at all. The local login form is
disabled unconditionally, so that is no way in.
Split the one gate into the two questions it was conflating:
- `ssoConfigured` — does this SWARM have an identity provider
(`swarm.authelia.url`, which is swarm-wide and whose own description
makes null mean "no SSO configured"). With a delivery route present
this is what emits Grafana's OIDC block.
- `ssoLocal` — is authelia on THIS host, now spelled as the forge and
matrix modules spell it. It decides only which unit delivers the
secret.
Where authelia is elsewhere, `swarm-bao-grafana-oidc.service` reads the
secret from the swarm secret store, shaped after
glue-queue-agent-credential.nix: cert login fails loudly because a retry
fixes every state it fails on, the read degrades quietly because no
retry turns "no value there" into a value, and nothing writes a
stand-in. The producer is the publisher that already runs on authelia's
host, which gains the swarm's service clients beside the per-hive ones
at `swarm/services/<id>/oidc/client` — with the write grant in
swarm-bao.nix and the hive read grant in `policy::render` to match.
Registration moved to glue-grafana-oidc-client.nix. It has to be
declared where authelia's config is rendered, and swarm-grafana.nix's
config block hangs off this host running Grafana.
Two judgement calls stated rather than buried: a hive's read policy now
grants the whole `services` prefix, because a service's path names the
service and nothing swarm-wide records which hive runs it (cost recorded
in docs/trust-boundary/security.md); and the client is registered on any
authelia host, because no swarm-wide "this swarm has a Grafana" fact
exists to gate it on.
Refs #4234
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The journald receiver runs with --lines=0, so every collector start
only ships what's written after it starts, and a restart silently
loses whatever landed while it was down. Point it at a file_storage
extension so the read cursor survives a restart; start_at stays at
its 'end' default since the cursor now covers everything after the
first run.
Refs #3818
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ports the subtle text-shadow glow @hive/agent's and the dashboard's own
headline rule already use (both independently converged on
`text-shadow: 0 0 Npx color-mix(color, transparent)`), not their whole
uppercase+letter-spacing headline typography -- that's those UIs' own
look, swarm-ui never adopted it and this issue only asked for the glow.
- Panel titles: `currentColor`-based, since a panel title has no one
fixed accent (some are dynamic, e.g. an agent's own name) -- a fixed
--purple glow on plain --fg text would read as a mismatched halo.
- Active nav tab: each item's own `accent` (NAV_ITEMS), the same value
its underline already uses, so the glow and the underline read as
one accent rather than two that happen to agree.
AgentsPage's table view (and its list+detail split) hits the same
60em readable-line-length cap the issue report's wide table already
opts out of via shell-body-wide. Adds /agents to WIDE_BODY_ROUTES --
the allowlist's own comment already anticipated this, a future wide
page reaches for the same class rather than inventing its own cap.
mara's review point on #4351: an agent isn't pinned to a hive forever
(it can move), so a URL naming one would go stale the moment it did.
Resolve the hive at request time from the agent-status bucket instead
-- the same source AgentStatusRow.hive already comes from -- rather
than trusting a caller-supplied value. Route is now
GET /api/agents/{name}/term/stream; a never-reported agent now answers
404 (no hive on record) instead of silently guessing.
hive-agent already publishes classified TermMsg rows to the core NATS
subject $SWARM.term.{hive}.{agent} -- live only, no retention, by
design. This endpoint subscribes that subject per request and relays
each row over SSE, opaque to this daemon (no TermMsg dependency, same
pass-through shape crate::status already uses for hive snapshots).
No replay/history: the publish side never grew JetStream retention, and
this route's own job (a live tail) never needed it.
extract validate_agent_names() and use it for both the parsed
agent-<name> inputs and run_meta_lock's pre-computed fanout list, so a
malformed name can't reach the new fast_forward_applied_main / lock_update
filesystem+git+forge-URL operations regardless of which of the two
sources it came from
argus + mara (PR #4339 review): the previous commit's per-agent lock
relock is a one-shot effect on the single rebuild the cascade triggers
- applied/<name> never moves, so the next relock=true rebuild trigger
(the boot sweep, most notably) re-locks against applied/<name> and
reverts straight back to whatever it was stuck on. The fix didn't
outlive the transaction it ran in.
New forge::fast_forward_applied_main(name), sibling to the existing
reseed-only fetch_config_main_into_applied: for an applied repo that
already has a .git and just needs to catch up, force-set rather than
fast-forward-gated since there's no PR to review on this path either.
Called per cascade agent right after the relock, best-effort so one
unreachable agent repo doesn't block the others.
Once applied/<name>/main has actually moved, lock_update_for_rebuild's
override (always reads current applied/<name>/main, no ?rev pin)
naturally stays in sync on any later relock=true rebuild instead of
reverting.
mara (hyperhive#4271): "whatever is on main is trusted and should be
pulled. dont make it periodic, just add it to the meta update when
choosing the agent."
A meta-input bump previously rebuilt every affected agent against
whatever applied/<name> was already locked to. Normally current, but
silently stale forever if a past deploy failed and nothing since
retried it — the manual meta-input trigger never special-cased that
either, since nothing wired it to check the config repo's live main at
all.
run_meta_lock now relocks each cascade agent's own input alongside the
originally-requested ones, against the input's declared source (the
forge URL) rather than the local applied/<name> mirror prepare_deploy
uses for a reviewed deploy — there's no PR to review on this path, so
nothing to gate. One combined lock_update call for the whole cascade:
simpler than per-agent isolation, at the cost of one broken/unreachable
agent repo failing the whole cascade relock rather than just that
agent (the separate top-level input bump above it is unaffected).
Known gap, not fixed here: applied/<name>'s own main/deployed/* tags
never advance from this path, only a real MergeConfigPr deploy does
that — so the audit trail stays as accurate as today, it just stops
being what actually got built.
fetch_total read issue_get_issue's comments field, Forgejo's running
counter on the Issue object that also increments for several
non-prose event kinds (review_request, issue_ref, comment_ref,
pull_push, ...) that issue_get_comments never returns. Diffing that
count against a fetched window reported drift that was never real: a
comment that would never be shown at any window size. Live repro on
PR #4333 (damocles's diagnosis on the issue): more_after: 2, both
events non-prose.
Fix: read the total straight off issue_get_comments's own
X-Total-Count header instead — the same endpoint that produces the
window, so the two populations can never drift apart again. Mirrors
timeline.rs's own fetch_total, which made the same move for its
endpoint first. fetch_head now captures the header from the request
it already makes (one fewer round trip in the --limit path); the
--tail/default path still probes once via page_size=1, same shape as
before but now scoped to the endpoint that actually produces the
window.
This also fixes the more serious half: fetch_tail derives its
pagination offset (which page holds the tail) from the same total, so
an inflated total didn't just skew the trailer's count, it could send
the offset math reaching for a page beyond the real thread's end,
returning fewer rows than requested or none at all when fetch_tail's
empty-page guard tripped. New test pins this against fetch_tail's
existing pagination-plan helper.
Refs #4335
hive-subagent-mcp already stamps a subagent=<name> resource attribute
(alongside the parent's own agent=<name>) on every claude_code.* sample
a spawned subagent turn emits -- the label already existed, it just
wasn't plotted anywhere. Adds five panels: subagent cost, subagent
turns, subagent cost share (of all cost), cost by subagent name, and
cost by parent agent. No backend changes needed.
The dashboard already templated an $agent variable and broke turns and
active-time out by agent, but cost and token totals only split by
model, effort and query_source -- there was no panel answering "how
much did each agent spend/use", the aggregate-by-agent view mara asked
for.
Same principle as the enum-enumeration fix, mara caught it in review:
the description said where full output lives, but format_task's own
answer already names the exact path when output was actually
truncated — the description doesn't need to say it too.
Mirrors #4333's split on the sibling hive-subagent-mcp surface (mara's
ruling there, quoted on #4336: "dont explain all the possible states
that can be returned in the tool description. instead explain the
status when returning it").
status_explanation() carries what each TaskStatus means and what to do
about it, appended to every format_task answer. The status tool's
description shrinks to what it's for; a caller only ever sees one
state at a time and now learns what it means without cross-referencing
anything else.
The `status` tool description enumerated all five states it can report, so
every caller paid for four answers it didn't get and read the explanation
in the wrong place. The description now states only what the tool is for
and that it costs nothing to call; each answer it returns carries its own
meaning and the caller's next move instead — running, starting and idle
were terse, the not-found error terser still, and they had been leaning on
the enumeration to be legible. The killed answer and the end-of-turn todo
are unchanged. `continue`'s description keeps its killed-resume sentence:
that describes what the tool does, not a state it might hand back.
Refs #4326
argus's review on #4333 flagged one real vale error (Microsoft.Contractions):
"did not" in the new "A killed turn" section reads as "didn't" instead. The
rest of the diff's new prose (docs/tools/subagent.md and the tool
descriptions in hive-subagent-mcp/src/mcp.rs) has no other instance of the
same expansion, confirmed both by a local `vale --minAlertLevel=error` run
(clean) and by grepping the added lines. Also tidies session.rs's module doc:
the two `//!` runs split to dodge the 30-line comment-block lint had a bare
trailing `//!` right before the blank separator; dropped so the first run
ends on content.
Refs #4326
A subagent whose claude process died on a signal — the kernel's OOM
killer, a stopped unit, an `interrupt` — was indistinguishable from one
that finished its turn: its entry left the `running` map, `status` fell
through to "a session exists on disk" and answered `idle`, and the
end-of-turn todo said the subagent had "finished". The usual next move
on that reading is `continue`, which resumes work that was cut mid-turn
with nothing having recorded that it was cut.
The driver already preserves how the child ended — `RunningClaude::wait`
returns `Error::Exit` carrying the `ExitStatus`, whose `signal()` is the
whole answer — so this reads it rather than having to recover it:
`classify_end` turns the outcome into `Complete` / `Killed { signal }` /
`Failed`, and `State::finish_turn` remembers a kill against the name
(cleared by the next confirmed spawn under it).
What an agent sees as a result:
- `status` reports the session killed, naming the signal, instead of idle;
- the todo the daemon pushes without being asked says the subagent was
KILLED mid-turn rather than that it finished;
- `continue` still resumes such a session, but its reply says the
previous turn was killed, so no caller carries on from cut-off work
believing it was complete.
Refs #4326
Three cases beside the existing ingest ones, since the read route has the
same trap and one property of its own.
- the route exists and carries `auth_request`;
- it has no login fallback — with the browser location as the positive
control, so a pass means the two routes differ rather than that
`error_page` and the login host are absent from the whole vhost;
- it injects no filter, on `extraConfig` and on `proxyPass` both, because
VictoriaLogs takes its filters as request parameters and those ride an
upstream URI as easily as a directive. A filter arriving later is then a
visible diff here rather than a quiet change of rule.
Each absence arm leads with a clause that proves the location resolved and
that `hasInfix` finds what is really in that string, so "not there" cannot
be read off an unreadable path.
Refs #3870
An agent can reach the log store only through the gateway, and the only
location that exists for a reader is `/`, which is the operator's browser
route. That route ends in `error_page 401 =302`, and an unauthenticated
caller which follows the redirect gets authelia's login page as HTTP 200
with an HTML body — so a client that checks the status code records a query
that succeeded and matched no logs. Measured on the live gateway; it is the
root cause behind four operator round-trips already.
So the query API gets its own location, `^~ /select/logsql/`, with bare
`auth_request` and no login fallback: an unauthenticated caller gets a 401
it cannot mistake for an empty result. `^~` keeps it ahead of the `/`
catch-all and of any regex location added later, and it stops short of
`/select/vmui/`, which is the browser UI and stays on the browser route.
The query is forwarded unmodified — no filter parameter is injected, so any
authenticated caller reads the whole swarm's logs. That is the rule mara
set: read permissions are a later thing, and this location is where one
attaches when it exists.
Refs #3870
A terminal row published on `$SWARM.term.<hive>.<agent>` goes out bare,
with no envelope around it and no server-side stamp, so a subscriber had
nothing to place the row in time with beyond its own receipt clock —
wrong by the queue's latency and meaningless for anything read later
than live.
`TermMsg` gains `ts`, ISO 8601 UTC. `classify` takes the event's own
unix-seconds stamp and applies it to every row that event expands into,
so a row replayed out of sqlite says when it happened rather than when
it was read, and a row that sat in a lagging subscriber's buffer does
not lie about its time. The oversize degrade keeps it; only the body is
ever spent.
`TermEnvelope` stops duplicating `ts` and keeps `seq`: the dedup counter
is a real transport concern, the event's time is not, now that it rides
on the row. Nothing in the frontend read `envelope.ts` — only the type
declared it.
Refs #4321
systemd's default OOMPolicy=stop tears the whole unit down the moment the
kernel kills any process in its cgroup, so a single over-large subagent
takes the daemon and every sibling session with it — measured on a live
agent, both units show OOMPolicy=stop today, which is exactly the "every
live subagent session was cut mid-turn" symptom.
That blast radius is also what would make the preceding commit a bad
trade: deliberately putting this unit first in the OOM queue is only an
improvement if losing one subagent isn't losing all of them. OOMPolicy=
continue scopes the loss to the process the kernel actually chose, and
leaves the daemon alive to report the kill instead of vanishing and being
restarted with an empty session map.
Refs #4316
Both units ran at OOMScoreAdjust=0, so under container memory pressure the
kernel picked purely on footprint — and the agent's own claude is often
the fattest process in the container, which means the session supervising
the work died before the work did.
The sign is the load-bearing part and is easy to invert: a HIGHER
OOMScoreAdjust means MORE likely to be killed, because the kernel adds it
to the badness score it derives from the process's memory footprint and
then kills the highest scorer. So hive-subagent-daemon gets +500 (first in
line) and hive-agent gets -500 (last in line). Written backwards this
makes the reported bug worse rather than better, so module-eval pins the
order as an inequality.
Both values are inherited by the nested claude each unit spawns as a
child, so ordering the units orders the sessions underneath them. -500
rather than -1000 on the harness: fully exempting it would leave the
kernel nothing to kill in a container whose only large process is the
harness.
Refs #4316
The daemon spawns every nested claude as a plain child, so its cgroup is
already the "all subagents" cgroup — but it ran with MemoryHigh=infinity
and MemoryMax=infinity, so nothing slowed a subagent down before the
kernel's OOM killer stopped the unit and cut every live session with it.
MemoryHigh= and not MemoryMax=: a soft ceiling reclaims and stalls the
cgroup past two thirds of the container's cap, which turns a silent kill
into a visible throttle, while still letting a single subagent exceed its
share when the container has memory free. A hard per-agent cap would make
overprovisioning impossible, which is not wanted — most of the time
nothing in these sessions is compiling.
The fraction is taken from hyperhive.claudeMemoryMaxBytes, the container's
own effective MemoryMax= that meta.rs already bakes in per agent. When
that is null (an `infinity` or percentage cap) the unit renders no ceiling
rather than a fabricated constant, and module-eval pins both arms.
Refs #4316
nix/devshell.nix didn't carry vale, so
[4mdocs/README.md[0m
16:51 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
53:49 [33mwarning[0m 'Multiple' is too wordy. write-good.TooWordy
60:33 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
62:14 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
74:12 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
88:12 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
[4mdocs/agent-lifecycle/agent-hierarchy.md[0m
5:59 [33mwarning[0m 'are meant' may be passive voice. Use active voice if you can. write-good.Passive
6:24 [33mwarning[0m 'is finished' may be passive voice. Use active voice if you can. write-good.Passive
7:1 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
23:36 [33mwarning[0m Consider 'stops responding' instead of 'hangs'. Microsoft.BiasFree
23:59 [33mwarning[0m 'is built' may be passive voice. Use active voice if you can. write-good.Passive
35:53 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
68:15 [33mwarning[0m 'are approved' may be passive voice. Use active voice if you can. write-good.Passive
104:12 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
107:47 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
126:3 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
135:15 [33mwarning[0m 'be gated' may be passive voice. Use active voice if you can. write-good.Passive
144:26 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
153:31 [33mwarning[0m 'is planned' may be passive voice. Use active voice if you can. write-good.Passive
157:32 [33mwarning[0m 'is handled' may be passive voice. Use active voice if you can. write-good.Passive
217:58 [33mwarning[0m 'be owned' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/getting-started/setup.md[0m
15:17 [33mwarning[0m 'is generated' may be passive voice. Use active voice if you can. write-good.Passive
51:38 [33mwarning[0m Consider using 'the app froze', 'the app stopped responding', 'the app stopped responding to events', or 'the app became unresponsive' instead of 'hang' (which may be insensitive). alex.Suicide
127:25 [33mwarning[0m 'usually' is a weasel word! write-good.Weasel
134:7 [33mwarning[0m 'whether or not' is too wordy. write-good.TooWordy
148:20 [33mwarning[0m 'it was' is too wordy. write-good.TooWordy
148:23 [33mwarning[0m 'was minted' may be passive voice. Use active voice if you can. write-good.Passive
160:23 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
163:40 [33mwarning[0m 'is bound' may be passive voice. Use active voice if you can. write-good.Passive
165:51 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
177:19 [33mwarning[0m 'is issued' may be passive voice. Use active voice if you can. write-good.Passive
183:36 [33mwarning[0m 'is tracked' may be passive voice. Use active voice if you can. write-good.Passive
200:31 [33mwarning[0m 'are gated' may be passive voice. Use active voice if you can. write-good.Passive
291:26 [33mwarning[0m 'is stored' may be passive voice. Use active voice if you can. write-good.Passive
297:22 [33mwarning[0m 'is authenticated' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/integrations/github.md[0m
16:79 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/integrations/knowledge.md[0m
17:58 [33mwarning[0m 'is read' may be passive voice. Use active voice if you can. write-good.Passive
56:61 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
94:3 [33mwarning[0m 'is stopped' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/integrations/forge.md[0m
35:24 [33mwarning[0m 'sufficient' is too wordy. write-good.TooWordy
109:54 [33mwarning[0m 'are shared' may be passive voice. Use active voice if you can. write-good.Passive
160:19 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'disabled'. alex.Ablist
171:1 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'Disabled'. alex.Ablist
331:1 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
[4mdocs/integrations/matrix.md[0m
34:47 [33mwarning[0m 'be changed' may be passive voice. Use active voice if you can. write-good.Passive
76:16 [33mwarning[0m 'are minted' may be passive voice. Use active voice if you can. write-good.Passive
172:67 [33mwarning[0m 'is restricted' may be passive voice. Use active voice if you can. write-good.Passive
200:61 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
202:22 [33mwarning[0m 'is trusted' may be passive voice. Use active voice if you can. write-good.Passive
207:61 [33mwarning[0m 'maximum' is too wordy. write-good.TooWordy
221:17 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'invalid'. alex.Ablist
226:28 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
231:26 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
233:27 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/agent-lifecycle/persistence.md[0m
7:27 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
16:46 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
23:15 [33mwarning[0m 'are kept' may be passive voice. Use active voice if you can. write-good.Passive
26:62 [33mwarning[0m 'however' is too wordy. write-good.TooWordy
32:33 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
92:13 [33mwarning[0m 'are kept' may be passive voice. Use active voice if you can. write-good.Passive
127:17 [33mwarning[0m 'was meant' may be passive voice. Use active voice if you can. write-good.Passive
177:23 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
185:6 [33mwarning[0m 'modify' is too wordy. write-good.TooWordy
249:38 [33mwarning[0m 'is wedged' may be passive voice. Use active voice if you can. write-good.Passive
249:65 [33mwarning[0m 'is stopped' may be passive voice. Use active voice if you can. write-good.Passive
278:5 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
349:12 [33mwarning[0m 'is read' may be passive voice. Use active voice if you can. write-good.Passive
356:11 [33mwarning[0m 'be confused' may be passive voice. Use active voice if you can. write-good.Passive
359:55 [33mwarning[0m 'are unrelated' may be passive voice. Use active voice if you can. write-good.Passive
413:43 [33mwarning[0m 'been removed' may be passive voice. Use active voice if you can. write-good.Passive
415:59 [33mwarning[0m 'be deleted' may be passive voice. Use active voice if you can. write-good.Passive
442:9 [33mwarning[0m 'is automigrated' may be passive voice. Use active voice if you can. write-good.Passive
454:58 [33mwarning[0m 'be removed' may be passive voice. Use active voice if you can. write-good.Passive
480:37 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
487:19 [33mwarning[0m 'is unaffected' may be passive voice. Use active voice if you can. write-good.Passive
494:18 [33mwarning[0m 'be started' may be passive voice. Use active voice if you can. write-good.Passive
582:51 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
591:28 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/agent-lifecycle/approvals.md[0m
34:36 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
141:43 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
150:42 [33mwarning[0m 'is overloaded' may be passive voice. Use active voice if you can. write-good.Passive
174:44 [33mwarning[0m 'Subsequent' is too wordy. write-good.TooWordy
190:27 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
295:23 [33mwarning[0m 'however' is too wordy. write-good.TooWordy
500:47 [33mwarning[0m 'additional' is too wordy. write-good.TooWordy
579:9 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
615:55 [33mwarning[0m 'previously' is too wordy. write-good.TooWordy
618:18 [33mwarning[0m 'was cleared' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/networking/network.md[0m
4:20 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
10:52 [33mwarning[0m 'were removed' may be passive voice. Use active voice if you can. write-good.Passive
18:61 [33mwarning[0m 'is untouched' may be passive voice. Use active voice if you can. write-good.Passive
84:33 [33mwarning[0m 'monitor' is too wordy. write-good.TooWordy
197:50 [33mwarning[0m 'is unchanged' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/process/pr-review-gate.md[0m
44:1 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
45:36 [33mwarning[0m 'are expected' may be passive voice. Use active voice if you can. write-good.Passive
50:13 [33mwarning[0m 'be armed' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/networking/snapshot-store.md[0m
126:49 [33mwarning[0m 'being enabled' may be passive voice. Use active voice if you can. write-good.Passive
127:9 [33mwarning[0m 'being set' may be passive voice. Use active voice if you can. write-good.Passive
131:15 [33mwarning[0m 'sufficient' is too wordy. write-good.TooWordy
164:43 [33mwarning[0m 'is discovered' may be passive voice. Use active voice if you can. write-good.Passive
178:5 [33mwarning[0m Reconsider using 'trap', it may be profane. alex.ProfanityMaybe
178:67 [33mwarning[0m 'being called' may be passive voice. Use active voice if you can. write-good.Passive
194:53 [33mwarning[0m 'is wanted' may be passive voice. Use active voice if you can. write-good.Passive
200:1 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
201:5 [33mwarning[0m 'is tracked' may be passive voice. Use active voice if you can. write-good.Passive
207:1 [33mwarning[0m 'is bounded' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/scheduler/ci.md[0m
34:1 [33mwarning[0m 'Several' is a weasel word! write-good.Weasel
37:7 [33mwarning[0m 'are required' may be passive voice. Use active voice if you can. write-good.Passive
69:27 [33mwarning[0m 'is stuck' may be passive voice. Use active voice if you can. write-good.Passive
131:98 [33mwarning[0m 'validate' is too wordy. write-good.TooWordy
146:33 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
186:55 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
188:422 [33mwarning[0m 'is dropped' may be passive voice. Use active voice if you can. write-good.Passive
193:60 [33mwarning[0m Reconsider using 'attack', it may be profane. alex.ProfanityMaybe
193:87 [33mwarning[0m 'eliminate' is too wordy. write-good.TooWordy
249:58 [33mwarning[0m 'however' is too wordy. write-good.TooWordy
[4mdocs/networking/gateway.md[0m
22:92 [33mwarning[0m 'is misconfigured' may be passive voice. Use active voice if you can. write-good.Passive
37:518 [33mwarning[0m 'is closed' may be passive voice. Use active voice if you can. write-good.Passive
105:40 [33mwarning[0m When referring to a person, consider using 'careless', 'heartless', 'indifferent', or 'insensitive' instead of 'blind to'. alex.Ablist
140:44 [33mwarning[0m 'is unchanged' may be passive voice. Use active voice if you can. write-good.Passive
142:4 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
154:38 [33mwarning[0m 'was removed' may be passive voice. Use active voice if you can. write-good.Passive
169:14 [33mwarning[0m 'is configured' may be passive voice. Use active voice if you can. write-good.Passive
170:48 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
177:15 [33mwarning[0m 'is covered' may be passive voice. Use active voice if you can. write-good.Passive
182:9 [33mwarning[0m Try to avoid using first-person plural like 'Let's'. Microsoft.We
190:12 [33mwarning[0m Try to avoid using first-person plural like 'Let's'. Microsoft.We
206:122 [33mwarning[0m Try to avoid using first-person plural like 'Let's'. Microsoft.We
212:153 [33mwarning[0m 'is named' may be passive voice. Use active voice if you can. write-good.Passive
224:185 [33mwarning[0m 'be wired' may be passive voice. Use active voice if you can. write-good.Passive
226:235 [33mwarning[0m 'terminate' is too wordy. write-good.TooWordy
230:150 [33mwarning[0m 'validate' is too wordy. write-good.TooWordy
230:261 [33mwarning[0m 'be added' may be passive voice. Use active voice if you can. write-good.Passive
232:165 [33mwarning[0m 'is undisturbed' may be passive voice. Use active voice if you can. write-good.Passive
234:199 [33mwarning[0m 'is wired' may be passive voice. Use active voice if you can. write-good.Passive
238:36 [33mwarning[0m Try to avoid using first-person plural like 'Let's'. Microsoft.We
276:68 [33mwarning[0m 'was removed' may be passive voice. Use active voice if you can. write-good.Passive
292:49 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
299:41 [33mwarning[0m 'is privileged' may be passive voice. Use active voice if you can. write-good.Passive
300:30 [33mwarning[0m 'be exposed' may be passive voice. Use active voice if you can. write-good.Passive
307:19 [33mwarning[0m 'was removed' may be passive voice. Use active voice if you can. write-good.Passive
311:40 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
358:25 [33mwarning[0m 'is left' may be passive voice. Use active voice if you can. write-good.Passive
361:11 [33mwarning[0m 'are opened' may be passive voice. Use active voice if you can. write-good.Passive
363:52 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
393:40 [33mwarning[0m 'requirement' is too wordy. write-good.TooWordy
501:13 [33mwarning[0m 'is broken' may be passive voice. Use active voice if you can. write-good.Passive
513:68 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
528:1 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
532:26 [33mwarning[0m 'is exposed' may be passive voice. Use active voice if you can. write-good.Passive
550:19 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
586:18 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
592:24 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'disabled'. alex.Ablist
620:7 [33mwarning[0m 'is encrypted' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/scheduler/jobq.md[0m
44:24 [33mwarning[0m 'is done' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/process/conventions.md[0m
81:55 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
139:40 [33mwarning[0m 'be handled' may be passive voice. Use active voice if you can. write-good.Passive
140:8 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
189:31 [33mwarning[0m 'are scoped' may be passive voice. Use active voice if you can. write-good.Passive
248:13 [33mwarning[0m 'be shown' may be passive voice. Use active voice if you can. write-good.Passive
274:24 [33mwarning[0m 'are kept' may be passive voice. Use active voice if you can. write-good.Passive
326:17 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
327:41 [33mwarning[0m 'are pushed' may be passive voice. Use active voice if you can. write-good.Passive
394:55 [33mwarning[0m 'Implement' is too wordy. write-good.TooWordy
432:1 [33mwarning[0m 'sufficient' is too wordy. write-good.TooWordy
434:12 [33mwarning[0m 'are factored' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/process/gotchas.md[0m
18:46 [33mwarning[0m 'are ignored' may be passive voice. Use active voice if you can. write-good.Passive
76:27 [33mwarning[0m 'be started' may be passive voice. Use active voice if you can. write-good.Passive
93:3 [33mwarning[0m 'enumerate' is too wordy. write-good.TooWordy
98:13 [33mwarning[0m 'it was' is too wordy. write-good.TooWordy
98:16 [33mwarning[0m 'was written' may be passive voice. Use active voice if you can. write-good.Passive
117:37 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
141:17 [33mwarning[0m Reconsider using 'trap', it may be profane. alex.ProfanityMaybe
148:26 [33mwarning[0m 'be wrapped' may be passive voice. Use active voice if you can. write-good.Passive
150:9 [33mwarning[0m 'is expected' may be passive voice. Use active voice if you can. write-good.Passive
160:25 [33mwarning[0m 'be reclaimed' may be passive voice. Use active voice if you can. write-good.Passive
161:28 [33mwarning[0m 'are gone' may be passive voice. Use active voice if you can. write-good.Passive
180:36 [33mwarning[0m Use first person (such as 'my') sparingly. Microsoft.FirstPerson
256:18 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
324:46 [33mwarning[0m 'are unused' may be passive voice. Use active voice if you can. write-good.Passive
355:59 [33mwarning[0m 'was checked' may be passive voice. Use active voice if you can. write-good.Passive
425:29 [33mwarning[0m 'is configured' may be passive voice. Use active voice if you can. write-good.Passive
438:27 [33mwarning[0m Use 'select' instead of the input-specific verb 'click'. Microsoft.UIVerbs
484:23 [33mwarning[0m 'is rooted' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/swarm/ca.md[0m
55:59 [33mwarning[0m 'is expected' may be passive voice. Use active voice if you can. write-good.Passive
56:9 [33mwarning[0m 'be ignored' may be passive voice. Use active voice if you can. write-good.Passive
65:60 [33mwarning[0m 'are distributed' may be passive voice. Use active voice if you can. write-good.Passive
74:10 [33mwarning[0m 'is issued' may be passive voice. Use active voice if you can. write-good.Passive
100:1 [33mwarning[0m 'terminate' is too wordy. write-good.TooWordy
110:26 [33mwarning[0m 'is allowed' may be passive voice. Use active voice if you can. write-good.Passive
145:31 [33mwarning[0m 'is misconfigured' may be passive voice. Use active voice if you can. write-good.Passive
164:31 [33mwarning[0m 'is assembled' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/scheduler/coordinator.md[0m
19:15 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
20:61 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
21:1 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'Special'. alex.Ablist
22:43 [33mwarning[0m 'is expressed' may be passive voice. Use active voice if you can. write-good.Passive
23:21 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
38:13 [33mwarning[0m 'be written' may be passive voice. Use active voice if you can. write-good.Passive
81:268 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
81:354 [33mwarning[0m 'is typed' may be passive voice. Use active voice if you can. write-good.Passive
93:68 [33mwarning[0m 'finalize' is too wordy. write-good.TooWordy
102:17 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
112:25 [33mwarning[0m 'finalize' is too wordy. write-good.TooWordy
209:51 [33mwarning[0m 'is satisfied' may be passive voice. Use active voice if you can. write-good.Passive
220:31 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
235:40 [33mwarning[0m 'requirement' is too wordy. write-good.TooWordy
241:1 [33mwarning[0m 'exclusively' is too wordy. write-good.TooWordy
244:5 [33mwarning[0m 'requirement' is too wordy. write-good.TooWordy
248:34 [33mwarning[0m 'requirement' is too wordy. write-good.TooWordy
256:51 [33mwarning[0m 'acquire' is too wordy. write-good.TooWordy
259:19 [33mwarning[0m 'is unaffected' may be passive voice. Use active voice if you can. write-good.Passive
280:39 [33mwarning[0m 'is tracked' may be passive voice. Use active voice if you can. write-good.Passive
343:24 [33mwarning[0m 'be kept' may be passive voice. Use active voice if you can. write-good.Passive
399:67 [33mwarning[0m 'finalize' is too wordy. write-good.TooWordy
419:25 [33mwarning[0m 'minimum' is too wordy. write-good.TooWordy
424:71 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
476:21 [33mwarning[0m 'is left' may be passive voice. Use active voice if you can. write-good.Passive
500:66 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
558:40 [33mwarning[0m 'is left' may be passive voice. Use active voice if you can. write-good.Passive
561:3 [33mwarning[0m 'additional' is too wordy. write-good.TooWordy
[4mdocs/swarm/secrets.md[0m
3:23 [33mwarning[0m 'are generated' may be passive voice. Use active voice if you can. write-good.Passive
7:23 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
17:37 [33mwarning[0m 'is published' may be passive voice. Use active voice if you can. write-good.Passive
32:42 [33mwarning[0m 'is responsible for' is too wordy. write-good.TooWordy
38:106 [33mwarning[0m 'is generated' may be passive voice. Use active voice if you can. write-good.Passive
46:110 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
57:139 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
70:78 [33mwarning[0m 'is made' may be passive voice. Use active voice if you can. write-good.Passive
80:10 [33mwarning[0m 'is made' may be passive voice. Use active voice if you can. write-good.Passive
80:36 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
81:47 [33mwarning[0m 'is registered' may be passive voice. Use active voice if you can. write-good.Passive
88:67 [33mwarning[0m 'is fed' may be passive voice. Use active voice if you can. write-good.Passive
120:39 [33mwarning[0m 'are required' may be passive voice. Use active voice if you can. write-good.Passive
167:44 [33mwarning[0m 'is wanted' may be passive voice. Use active voice if you can. write-good.Passive
187:36 [33mwarning[0m 'be fetched' may be passive voice. Use active voice if you can. write-good.Passive
207:34 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
212:24 [33mwarning[0m 'is built' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/swarm/README.md[0m
6:5 [33mwarning[0m 'additional' is too wordy. write-good.TooWordy
6:51 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
21:24 [33mwarning[0m 'be qualified' may be passive voice. Use active voice if you can. write-good.Passive
43:67 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
50:10 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
130:62 [33mwarning[0m Use first person (such as 'my') sparingly. Microsoft.FirstPerson
131:1 [33mwarning[0m 'is derived' may be passive voice. Use active voice if you can. write-good.Passive
158:34 [33mwarning[0m 'was removed' may be passive voice. Use active voice if you can. write-good.Passive
168:10 [33mwarning[0m 'be listed' may be passive voice. Use active voice if you can. write-good.Passive
171:52 [33mwarning[0m 'is tracked' may be passive voice. Use active voice if you can. write-good.Passive
274:1 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
278:48 [33mwarning[0m 'is documented' may be passive voice. Use active voice if you can. write-good.Passive
293:66 [33mwarning[0m 'is installed' may be passive voice. Use active voice if you can. write-good.Passive
377:41 [33mwarning[0m 'is opened' may be passive voice. Use active voice if you can. write-good.Passive
388:39 [33mwarning[0m 'been given' may be passive voice. Use active voice if you can. write-good.Passive
413:27 [33mwarning[0m 'are expected' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/scheduler/observability.md[0m
40:23 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
60:24 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
64:48 [33mwarning[0m 'be read' may be passive voice. Use active voice if you can. write-good.Passive
75:60 [33mwarning[0m 'is unchanged' may be passive voice. Use active voice if you can. write-good.Passive
148:51 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
193:19 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
205:22 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
215:8 [33mwarning[0m 'additional' is too wordy. write-good.TooWordy
221:11 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
243:51 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
251:11 [33mwarning[0m 'is unauthenticated' may be passive voice. Use active voice if you can. write-good.Passive
256:11 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
283:18 [33mwarning[0m 'is measured' may be passive voice. Use active voice if you can. write-good.Passive
284:13 [33mwarning[0m 'are measured' may be passive voice. Use active voice if you can. write-good.Passive
286:33 [33mwarning[0m 'is gone' may be passive voice. Use active voice if you can. write-good.Passive
311:49 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
351:59 [33mwarning[0m 'be repeated' may be passive voice. Use active voice if you can. write-good.Passive
391:67 [33mwarning[0m 'is unaffected' may be passive voice. Use active voice if you can. write-good.Passive
396:38 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
[4mdocs/tools/README.md[0m
45:56 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
[4mdocs/swarm/ui.md[0m
45:63 [33mwarning[0m 'were supposed' may be passive voice. Use active voice if you can. write-good.Passive
80:61 [33mwarning[0m 'is scoped' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/swarm/services.md[0m
20:61 [33mwarning[0m 'be set' may be passive voice. Use active voice if you can. write-good.Passive
49:55 [33mwarning[0m 'be set' may be passive voice. Use active voice if you can. write-good.Passive
79:1 [33mwarning[0m 'are created' may be passive voice. Use active voice if you can. write-good.Passive
102:1 [33mwarning[0m 'be restarted' may be passive voice. Use active voice if you can. write-good.Passive
123:48 [33mwarning[0m 'is configured' may be passive voice. Use active voice if you can. write-good.Passive
148:170 [33mwarning[0m 'being written' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/bash.md[0m
26:61 [33mwarning[0m 'is created' may be passive voice. Use active voice if you can. write-good.Passive
33:36 [33mwarning[0m 'is created' may be passive voice. Use active voice if you can. write-good.Passive
58:53 [33mwarning[0m 'is expected' may be passive voice. Use active voice if you can. write-good.Passive
128:40 [33mwarning[0m 'is rendered' may be passive voice. Use active voice if you can. write-good.Passive
136:26 [33mwarning[0m 'been removed' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/swarm/sso.md[0m
5:8 [33mwarning[0m 'is declared' may be passive voice. Use active voice if you can. write-good.Passive
31:62 [33mwarning[0m 'been enabled' may be passive voice. Use active voice if you can. write-good.Passive
70:21 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
98:61 [33mwarning[0m 'is tabulated' may be passive voice. Use active voice if you can. write-good.Passive
118:14 [33mwarning[0m 'is built' may be passive voice. Use active voice if you can. write-good.Passive
127:26 [33mwarning[0m 'is broken' may be passive voice. Use active voice if you can. write-good.Passive
241:23 [33mwarning[0m 'was verified' may be passive voice. Use active voice if you can. write-good.Passive
241:60 [33mwarning[0m 'was introduced' may be passive voice. Use active voice if you can. write-good.Passive
257:42 [33mwarning[0m 'are created' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/lifecycle.md[0m
16:32 [33mwarning[0m 'is preserved' may be passive voice. Use active voice if you can. write-good.Passive
55:1 [33mwarning[0m 'Subsequent' is too wordy. write-good.TooWordy
[4mdocs/tools/forge.md[0m
21:8 [33mwarning[0m 'is assumed' may be passive voice. Use active voice if you can. write-good.Passive
28:36 [33mwarning[0m 'validate' is too wordy. write-good.TooWordy
35:18 [33mwarning[0m 'be seen' may be passive voice. Use active voice if you can. write-good.Passive
35:43 [33mwarning[0m 'is stated' may be passive voice. Use active voice if you can. write-good.Passive
40:3 [33mwarning[0m 'are removed' may be passive voice. Use active voice if you can. write-good.Passive
45:22 [33mwarning[0m 'validate' is too wordy. write-good.TooWordy
137:1 [33mwarning[0m 'Multiple' is too wordy. write-good.TooWordy
144:144 [33mwarning[0m 'are merged' may be passive voice. Use active voice if you can. write-good.Passive
154:51 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
158:8 [33mwarning[0m 'are read' may be passive voice. Use active voice if you can. write-good.Passive
178:61 [33mwarning[0m 'be run' may be passive voice. Use active voice if you can. write-good.Passive
313:38 [33mwarning[0m 'are structured' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/scheduling.md[0m
23:1 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
25:45 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
33:8 [33mwarning[0m 'are left' may be passive voice. Use active voice if you can. write-good.Passive
34:54 [33mwarning[0m 'previously' is too wordy. write-good.TooWordy
46:31 [33mwarning[0m 'is removed' may be passive voice. Use active voice if you can. write-good.Passive
96:16 [33mwarning[0m 'minimum' is too wordy. write-good.TooWordy
[4mdocs/tools/matrix.md[0m
6:9 [33mwarning[0m 'is configured' may be passive voice. Use active voice if you can. write-good.Passive
31:35 [33mwarning[0m 'is inferred' may be passive voice. Use active voice if you can. write-good.Passive
32:34 [33mwarning[0m 'is sent' may be passive voice. Use active voice if you can. write-good.Passive
46:20 [33mwarning[0m 'enumerate' is too wordy. write-good.TooWordy
63:43 [33mwarning[0m 'been invited' may be passive voice. Use active voice if you can. write-good.Passive
70:4 [33mwarning[0m 'Multiple' is too wordy. write-good.TooWordy
74:64 [33mwarning[0m 'is keyed' may be passive voice. Use active voice if you can. write-good.Passive
111:18 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
113:5 [33mwarning[0m 'Multiple' is too wordy. write-good.TooWordy
130:51 [33mwarning[0m 'was dropped' may be passive voice. Use active voice if you can. write-good.Passive
141:1 [33mwarning[0m 'is cleared' may be passive voice. Use active voice if you can. write-good.Passive
149:39 [33mwarning[0m 'additional' is too wordy. write-good.TooWordy
[4mdocs/tools/subagent.md[0m
44:11 [33mwarning[0m 'are meant' may be passive voice. Use active voice if you can. write-good.Passive
44:24 [33mwarning[0m 'be bounded' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/hivectl.md[0m
46:24 [33mwarning[0m 'is created' may be passive voice. Use active voice if you can. write-good.Passive
100:53 [33mwarning[0m 'is needed' may be passive voice. Use active voice if you can. write-good.Passive
136:67 [33mwarning[0m 'is hoisted' may be passive voice. Use active voice if you can. write-good.Passive
157:38 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
205:46 [33mwarning[0m 'previously' is too wordy. write-good.TooWordy
222:1 [33mwarning[0m 'requirement' is too wordy. write-good.TooWordy
224:12 [33mwarning[0m 'were added' may be passive voice. Use active voice if you can. write-good.Passive
231:1 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
244:35 [33mwarning[0m 'be consumed' may be passive voice. Use active voice if you can. write-good.Passive
245:52 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
246:6 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/swarmctl-cli.md[0m
70:62 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
119:19 [33mwarning[0m 'was generated' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/hivectl-cli.md[0m
250:118 [33mwarning[0m 'is created' may be passive voice. Use active voice if you can. write-good.Passive
506:331 [33mwarning[0m 'is required' may be passive voice. Use active voice if you can. write-good.Passive
506:357 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
644:9 [33mwarning[0m 'is staged' may be passive voice. Use active voice if you can. write-good.Passive
907:19 [33mwarning[0m 'was generated' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/tools/forge-cli.md[0m
146:68 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
176:192 [33mwarning[0m 'is created' may be passive voice. Use active voice if you can. write-good.Passive
246:161 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
284:48 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
296:37 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
345:51 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
351:54 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
351:90 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
352:47 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
363:43 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
363:79 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
371:37 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
401:51 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
407:87 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
418:40 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
461:159 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
483:78 [33mwarning[0m 'are left' may be passive voice. Use active voice if you can. write-good.Passive
490:72 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
654:67 [33mwarning[0m 'are left' may be passive voice. Use active voice if you can. write-good.Passive
706:161 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
744:48 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
756:37 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
805:55 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
811:54 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
811:90 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
812:47 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
823:43 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
823:79 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
831:37 [33mwarning[0m 'is blocked' may be passive voice. Use active voice if you can. write-good.Passive
861:51 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
867:87 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
878:40 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
921:159 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
980:94 [33mwarning[0m 'is given' may be passive voice. Use active voice if you can. write-good.Passive
988:84 [33mwarning[0m 'be cloned' may be passive voice. Use active voice if you can. write-good.Passive
1041:76 [33mwarning[0m 'in addition' is too wordy. write-good.TooWordy
1041:123 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
1042:23 [33mwarning[0m 'Maximum' is too wordy. write-good.TooWordy
1139:240 [33mwarning[0m When referring to a person, consider using 'correct', 'adequate', 'sufficient', 'consistent', 'valid', 'coherent', 'sensible', or 'reasonable' instead of 'sane'. alex.Ablist
1402:19 [33mwarning[0m 'was generated' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/trust-boundary/boundary.md[0m
5:32 [33mwarning[0m 'is tracked' may be passive voice. Use active voice if you can. write-good.Passive
52:64 [33mwarning[0m 'are served' may be passive voice. Use active voice if you can. write-good.Passive
58:61 [33mwarning[0m 'be bound' may be passive voice. Use active voice if you can. write-good.Passive
60:62 [33mwarning[0m 'is treated' may be passive voice. Use active voice if you can. write-good.Passive
99:27 [33mwarning[0m 'is shared' may be passive voice. Use active voice if you can. write-good.Passive
112:13 [33mwarning[0m 'is declared' may be passive voice. Use active voice if you can. write-good.Passive
122:46 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
124:15 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
131:21 [33mwarning[0m 'be opened' may be passive voice. Use active voice if you can. write-good.Passive
151:53 [33mwarning[0m 'is added' may be passive voice. Use active voice if you can. write-good.Passive
157:4 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
[4mdocs/web-ui/README.md[0m
107:17 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
131:28 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
[4mdocs/turn-loop/config.md[0m
107:8 [33mwarning[0m 'additional' is too wordy. write-good.TooWordy
205:33 [33mwarning[0m 'evaluate' is too wordy. write-good.TooWordy
219:21 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'Disabled'. alex.Ablist
263:42 [33mwarning[0m Use first person (such as 'I') sparingly. Microsoft.FirstPerson
292:66 [33mwarning[0m 'is documented' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/trust-boundary/security.md[0m
13:1 [33mwarning[0m 'is trusted' may be passive voice. Use active voice if you can. write-good.Passive
16:25 [33mwarning[0m 'is privileged' may be passive voice. Use active voice if you can. write-good.Passive
17:61 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
25:64 [33mwarning[0m 'be stopped' may be passive voice. Use active voice if you can. write-good.Passive
39:35 [33mwarning[0m When referring to a person, consider using 'foolish', 'ludicrous', 'speechless', or 'silent' instead of 'dumb'. alex.Ablist
39:35 [33mwarning[0m Don't use 'dumb', it's profane. alex.ProfanityLikely
39:61 [33mwarning[0m 'is affected' may be passive voice. Use active voice if you can. write-good.Passive
82:17 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
91:57 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
196:24 [33mwarning[0m 'therefore' is too wordy. write-good.TooWordy
212:62 [33mwarning[0m 'is tracked' may be passive voice. Use active voice if you can. write-good.Passive
226:49 [33mwarning[0m 'be steered' may be passive voice. Use active voice if you can. write-good.Passive
280:26 [33mwarning[0m 'is scoped' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/turn-loop/mcp.md[0m
117:34 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
143:3 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'disabled'. alex.Ablist
219:8 [33mwarning[0m 'is disallowed' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/turn-loop/claude-invocation.md[0m
116:54 [33mwarning[0m 'is gone' may be passive voice. Use active voice if you can. write-good.Passive
237:8 [33mwarning[0m 'is shared' may be passive voice. Use active voice if you can. write-good.Passive
245:32 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
247:30 [33mwarning[0m 'are mounted' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/web-ui/css-vars.md[0m
36:12 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
141:35 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
[4mdocs/web-ui/design-guide.md[0m
8:30 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
18:24 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
19:41 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
34:30 [33mwarning[0m 'minimize' is too wordy. write-good.TooWordy
49:67 [33mwarning[0m 'is hidden' may be passive voice. Use active voice if you can. write-good.Passive
94:56 [33mwarning[0m 'is hidden' may be passive voice. Use active voice if you can. write-good.Passive
131:61 [33mwarning[0m 'minimum' is too wordy. write-good.TooWordy
145:21 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
149:55 [33mwarning[0m 'consolidate' is too wordy. write-good.TooWordy
155:26 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
158:1 [33mwarning[0m Consider using 'simple', 'indigenous', or 'hunter-gatherer' instead of 'primitive'. alex.Race
[4mdocs/web-ui/shape.md[0m
41:17 [33mwarning[0m 'is sanitized' may be passive voice. Use active voice if you can. write-good.Passive
127:51 [33mwarning[0m 'are unaffected' may be passive voice. Use active voice if you can. write-good.Passive
131:46 [33mwarning[0m Use first person (such as 'me') sparingly. Microsoft.FirstPerson
184:1 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
195:66 [33mwarning[0m 'is sanitized' may be passive voice. Use active voice if you can. write-good.Passive
230:7 [33mwarning[0m 'is hidden' may be passive voice. Use active voice if you can. write-good.Passive
232:32 [33mwarning[0m 'are reused' may be passive voice. Use active voice if you can. write-good.Passive
247:43 [33mwarning[0m 'is gone' may be passive voice. Use active voice if you can. write-good.Passive
253:1 [33mwarning[0m Use 'select' instead of the input-specific verb 'swipes'. Microsoft.UIVerbs
301:28 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
[4mdocs/web-ui/agent.md[0m
49:62 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
75:21 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
78:34 [33mwarning[0m Use 'select' instead of the input-specific verb 'click'. Microsoft.UIVerbs
95:59 [33mwarning[0m 'are typed' may be passive voice. Use active voice if you can. write-good.Passive
131:34 [33mwarning[0m Reconsider using 'trap', it may be profane. alex.ProfanityMaybe
135:43 [33mwarning[0m 'is unchanged' may be passive voice. Use active voice if you can. write-good.Passive
176:36 [33mwarning[0m 'been removed' may be passive voice. Use active voice if you can. write-good.Passive
270:48 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'invalid'. alex.Ablist
271:39 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'invalid'. alex.Ablist
273:12 [33mwarning[0m 'is called' may be passive voice. Use active voice if you can. write-good.Passive
335:3 [33mwarning[0m 'subsequent' is too wordy. write-good.TooWordy
367:35 [33mwarning[0m 'minimum' is too wordy. write-good.TooWordy
377:56 [33mwarning[0m Use 'select' instead of the input-specific verb 'clicks'. Microsoft.UIVerbs
[4mdocs/web-ui/dashboard.md[0m
61:51 [33mwarning[0m 'be confused' may be passive voice. Use active voice if you can. write-good.Passive
183:32 [33mwarning[0m 'equivalent' is too wordy. write-good.TooWordy
251:46 [33mwarning[0m 'is checked' may be passive voice. Use active voice if you can. write-good.Passive
261:35 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
314:25 [33mwarning[0m 'is unchanged' may be passive voice. Use active voice if you can. write-good.Passive
342:29 [33mwarning[0m 'is tooltipped' may be passive voice. Use active voice if you can. write-good.Passive
386:13 [33mwarning[0m 'however' is too wordy. write-good.TooWordy
447:50 [33mwarning[0m 'is written' may be passive voice. Use active voice if you can. write-good.Passive
451:65 [33mwarning[0m 'are named' may be passive voice. Use active voice if you can. write-good.Passive
466:22 [33mwarning[0m When referring to a person, consider using 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'special'. alex.Ablist
524:29 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'Disabled'. alex.Ablist
537:33 [33mwarning[0m 'originally-active' doesn't need a hyphen. Microsoft.Hyphens
763:29 [33mwarning[0m 'is stopped' may be passive voice. Use active voice if you can. write-good.Passive
771:48 [33mwarning[0m 'is enabled' may be passive voice. Use active voice if you can. write-good.Passive
778:14 [33mwarning[0m 'all of' is too wordy. write-good.TooWordy
798:22 [33mwarning[0m 'is stopped' may be passive voice. Use active voice if you can. write-good.Passive
830:3 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
856:16 [33mwarning[0m 'exclusively' is too wordy. write-good.TooWordy
951:33 [33mwarning[0m Reconsider using 'trap', it may be profane. alex.ProfanityMaybe
1016:23 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'disabled'. alex.Ablist
1017:22 [33mwarning[0m 'is mixed' may be passive voice. Use active voice if you can. write-good.Passive
1027:22 [33mwarning[0m When referring to a person, consider using 'turned off', 'has a disability', 'person with a disability', or 'people with disabilities' instead of 'disabled'. alex.Ablist
1028:63 [33mwarning[0m 'satisfy' is too wordy. write-good.TooWordy
1038:9 [33mwarning[0m 'multiple' is too wordy. write-good.TooWordy
1075:47 [33mwarning[0m 'is set' may be passive voice. Use active voice if you can. write-good.Passive
1077:57 [33mwarning[0m 'be created' may be passive voice. Use active voice if you can. write-good.Passive
1109:50 [33mwarning[0m 'is focused' may be passive voice. Use active voice if you can. write-good.Passive
1256:17 [33mwarning[0m 'is written' may be passive voice. Use active voice if you can. write-good.Passive
1272:3 [33mwarning[0m 'is sent' may be passive voice. Use active voice if you can. write-good.Passive
1273:15 [33mwarning[0m 'previously' is too wordy. write-good.TooWordy
1286:3 [33mwarning[0m 'is untouched' may be passive voice. Use active voice if you can. write-good.Passive
1391:27 [33mwarning[0m 'is gone' may be passive voice. Use active voice if you can. write-good.Passive
✖ [31m0 errors[0m, [33m493 warnings[0m and [34m0 suggestions[0m in 50 files. failed
with "vale: not found" even though hive-rules says to gate locally with
the devshell — a builder had to reconstruct CI's incantation by hand.
Local command: XDG_DATA_HOME=$PWD/.vale-data nix develop -c sh -c 'vale sync && vale docs'
The queue's payload ceiling was justified by what the queue was about to
carry; it carries it now, so the comment says so.
The other two sites say "a hive with no queue configured". The swarm has
exactly one queue and a hive cannot lack it — only its coordinates, its
credential, or its ability to reach it. That wording is already used
everywhere else the absence is named; these two predate it.
The docs section on the agents' queue coordinates stopped at delivering
them and never said what the connection is for. It now names the subject
and the degrade rule, which is the part an operator reading an agent's
terminal at the swarm needs.
Refs #3805
The harness has had its queue coordinates since the credential reached
the container, but nothing used them. This offers each terminal row
upward on `$SWARM.term.<hive>.<agent>`, so a swarm-level terminal can
render an agent without reaching into the hive that hosts it.
It publishes the same `TermMsg` the web UI is handed rather than a
second model of the same events, so a new tool or a reclassified event
changes both surfaces together. It subscribes to the event bus rather
than to the SSE handler: the handler classifies per connected browser,
so hanging this off it would mean an agent nobody is watching publishes
nothing. That also means its own long-lived `ClassifyCtx`, since a
publisher restarting its correlation state would lose the `tool_use` →
name mapping a `tool_result` needs to render.
The hive in the subject is derived from the queue client id, not from
the harness's hive display name. Those come from different sources with
no rule tying them together, and the responder builds its grant from the
client id — so deriving it from the display name yields a publish the
broker refuses, reaching an operator as a terminal that is merely empty.
The prefix and suffix that bracket the hive are the responder's flags,
which the agent is not told; it restates their defaults, and the symptom
of a deployment retuning one without changing this is every publish
refused rather than a wrong subject accepted.
Oversize rows degrade in the publisher. Exceeding `max_payload` is not a
truncation: the server refuses the message and closes the connection, so
an oversize publish costs the row, the connection, and the rows racing
behind it through the reconnect. The body is the only unbounded field —
summaries are already trimmed at classification — so it is the field
spent, and the row keeps its icon, level, summary and coalesce key. A
row that does not fit even then is logged and dropped rather than sent.
The limit is read off the connection, so `8388608` stays spelled once in
the queue's own module; size is measured by serializing, because JSON
escaping separates character count from wire length by an unbounded
factor on exactly the rows already near the limit.
Best-effort throughout: no queue, an unparseable client id and a failed
connect each disable the publisher with one log line, and a failed
publish loses its row and nothing else. The turn loop and the web UI
never block on the queue.
Refs #3805
A publisher of variable-size rows has to size them against the server's
limit before it publishes, because exceeding it is not a truncation: the
server answers `Maximum Payload Violation` and closes the connection, so
the row is lost and the client reconnects.
The limit belongs to the queue's NixOS module, which is the only place
that chooses it. Reading it off the connection rather than restating it
as a constant keeps it spelled once — a client-side copy would be a
second opinion about a number it does not own, and would go stale the
day an operator raised the real one.
No test: the value comes from the server's INFO line, so anything
asserted about it without a running server would only be re-asserting
async-nats's own pre-connect default.
Refs #3805
The responder has had an agent arm since the principal was minted, but
no deployment ever passed `--agent-publish-subject`, and an empty list
is a refusal by design: `Policy::permissions` returns `None` rather than
a grant that can do nothing, so every agent was turned away at CONNECT.
The subject itself is the one this thread settled on, `$SWARM.term`
namespaced per hive.
The value has to reach the responder with a literal dollar. systemd
substitutes `$NAME` in `ExecStart` whether or not the word is quoted,
so a single dollar expands `SWARM` — unset, therefore empty — and the
responder is handed `.term.{hive}.>`. That grant validates (it carries
the `{hive}` placeholder), is accepted, and matches nothing any agent
publishes to, so the failure surfaces as an authorization violation far
from its cause. `$$` in the unit text is the escape for one dollar.
The module-eval case reads the rendered unit rather than the module
source, because the single-dollar version renders perfectly well; the
doubled dollar is the only thing that distinguishes them before deploy.
The grant is per-hive, not per-agent: an agent's identity names its
hive, so any agent in a hive can publish as another. That is the
tradeoff ruled acceptable for now, tracked separately for tightening.
Refs #3805
The swarm always has exactly one queue; a hive can only lack its
address. Reworded every prose site this PR added that stated or
implied the opposite, to name what is actually absent (coordinates,
credential, or address) instead of the queue itself.
Refs #3805
The host end: `HIVE_C0RE_AGENT_QUEUE_CREDENTIAL_DIR` tells the daemon
where the reader unit put the files, and a new
`deploy.hive-controller.queue.agentNatsUrl` says where the queue is as an
agent *container* reaches it. That address defaults to the bridge one and
never to loopback — `statusPublish.natsUrl` beside it is loopback and
correct, because hive-c0re shares the host netns and an agent does not.
Paired with the swarm's token endpoint, gated together, and forwarded by
`hive_c0re::meta` as both an env var and an agent option: the harness
reads the variable at runtime, its unit is built from the option.
The agent end: `nix/agent-modules/queue.nix` declares that option pair
and, when set, has the harness unit inherit the two credentials by name.
Bare-id `LoadCredential=` is the terse form documented for inheriting
what the service manager received, and is non-fatal when the credential
is absent — which a hive whose publisher has not run yet needs.
No `HIVE_AGENT_OIDC_CA_FILE`: the meta flake already embeds the hive CA
and the swarm root into each container's trust store at build time, and
reqwest's rustls backend verifies against it.
Refs #3805
hive-c0re stats the two files `swarm-bao-queue-agent` lands and forwards
them into every agent container as systemd credentials, and the harness
resolves a `QueueConfig` out of them at boot. Nothing connects yet.
A credential and not a bind mount, and the mode is what forces it: the
secret is root:0600 and the harness runs as the unprivileged agent user,
so a bind would deliver a file that user cannot open. nspawn's
`--load-credential` is read by the container manager as root and
re-exposed under the consuming unit's own `User=`. hive-c0re never reads
the bytes either way, which is just as well — it runs as `hive-core`.
Absent files stay legal and become visible rather than silent: the
publisher lives on the authelia host and mints on its first boot, so
"nothing at that path" is the ordinary early state of a swarm. c0re
forwards nothing and logs why; the harness logs that it has no queue.
The client id comes out of the delivered file rather than being rebuilt
from `hiveName` in nix, which is the agreement `swarm-secret-client`
states. `QueueConfig::from_env` wants it as a value, so the harness reads
the file itself — assigning the variable instead would need
`std::env::set_var` in a process that has already spawned threads.
Refs #3805
Ruled: swarm-bao-queue-agent.service must run before hive-c0re.service
and be wanted (not required) by it, so no agent container renders
ahead of the reader's attempt at its credential. An unreachable store
delays hive-c0re's start by the reader's own start-limit window rather
than failing it outright.
Refs #4314