deploy-agent used bare `ssh <host>` / `rsync <host>:` (→ <host>.lan), which
fails off-LAN or when the direct plum→host WG relay drops — blocking deploys
even though the host is reachable via the black jump host. Now it probes
<host> → <host>-wg → <host>-j and uses the first that answers for the ssh/rsync
legs (remote-run keeps its own routing), keeping the claire host LABEL as
<host>. Override with CLAIRE_SSH_ALIAS. Verified: apricot deployed via apricot-j
while .lan + -wg were timing out.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire the rounds timer to a pure-Python skip gate so claire-serve only wakes
the orchestrator model when worker fleet state changed (not every tick):
- web/rounds.py: fleet_fingerprint() over worker sessions (minus the
orchestrator's own) + open tasks; should_skip_round() with heartbeat floor.
- web/app.py: _rounds_loop tracks last fingerprint + consecutive skips.
- excludes the orchestrator's own session/chat so a round's self-side-effects
can't defeat the gate.
Add scripts/release-fleet.sh (test -> deploy apricot+black -> restart plum
services) and harden deploy-agent.sh's cosmetic status check against a SIGPIPE
false-abort. 3 new discriminating tests; 349 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Peer nodes can run a local orchestrator registered with claude.ai/code as
[<host>] claire, installed uniformly via deploy-agent.sh (not hand-wired).
- agent.orchestrator_enable + orchestrator.mcp_url config (round-trip safe)
- bootstrap points orchestrator MCP at central endpoint when set
- peer lifespan bootstraps + heartbeats the orchestrator (NO rounds loop)
- claire agent enable-orchestrator CLI + deploy-agent.sh wiring
(manual commit via ALLOW_COMMIT=1 — autocommit LLM was timing out on claire)