hive-c0re: converge when the controller republishes, not only at boot

The wanted-state read was a boot-time DAG node, so a swarm-level change sat
unapplied until the next restart. This watches the hive's own bucket and
converges on each update.

It does not replace the boot read: a watch hears only what is published while
it is listening, so a hive that was down still learns the current declaration
from `pull`. The watch is the fast path, `pull` stays the repair path.

Rides the connection swarm-status already opens, as a third consumer — a
second connect would double the auth-callout traffic and give the two paths
independent reconnect state, which is the reason the deploy-event drain is
spawned there too.

A delete is not a deletion order. `carries_a_declaration` is pure and tested
so that rule is enforced rather than asserted: converging on a withdrawn key
would tear down exactly the agents "absence is not a deletion order" protects.
This commit is contained in:
atlas 2026-09-03 00:36:15 +02:00
commit 5f733493f1
3 changed files with 146 additions and 1 deletions

View file

@ -89,6 +89,15 @@ pub fn spawn(
// the other was still down. `async_nats::Client` is a handle, so the
// clone is cheap.
tokio::spawn(drain_swarm_events(
client.clone(),
std::sync::Arc::clone(&coord),
hive.clone(),
shutdown.clone(),
));
// The wanted-state watch rides the same connection for the same
// reason, and is a third consumer rather than a second connection.
tokio::spawn(crate::workers::wanted::watch_declarations(
client.clone(),
coord,
hive.clone(),