Watch
0
0
Fork
You've already forked hyperhive
0

hive: stop controlling the swarm's forge and matrix containers

The forge and matrix are swarm services; per mara's ruling on #5475
(shape a) a hive no longer starts, stops or restarts them.

- hive-priv-sock: InfraContainer keeps only Gateway; InfraTarget goes,
  service_unit maps the gateway to nginx.service directly. A
  ControlInfraContainer naming Forge/Matrix fails to decode.
- hive-host-sock: LifecycleScope drops forge/matrix and refuses unknown
  fields, so an older hivectl's --forge is an error rather than an
  all-false scope meaning everything.
- hive-c0re: scoped_infra selects only the gateway.
- hivectl: --forge/--matrix removed from stop/start/restart.
- docs: services.md says how the forge and matrix are managed;
  security.md, coordinator.md and hivectl-cli.md follow.
- hive-host-sock, hivectl/power.rs: Stop and RestartScoped doc comments name the gateway (host nginx.service), not infra containers.
This commit is contained in:
atlas 2026-10-17 22:52:18 +02:00 • committed by mara
commit d4f3d1ef8e
12 changed files with 177 additions and 203 deletions

View file

@ -136,9 +136,9 @@ pub enum HostRequest {
/// follow-up, since nothing durable remembered "finish the restart"
/// once the calling process/turn was gone. `GracefulRestart` closes
/// that gap the same way `Restart` already does — one DAG, queued up
/// front, that owns the whole sequence. Infra containers have no
/// lease/DAG and restart synchronously (stop then start), same as
/// before. Scope semantics match `Stop`/`Start` (all-false =
/// front, that owns the whole sequence. The gateway (host
/// `nginx.service`) has no lease/DAG and restarts synchronously
/// (stop then start). Scope semantics match `Stop`/`Start` (all-false =
/// everything).
RestartScoped {
#[serde(default)]
@ -204,12 +204,12 @@ pub enum HostRequest {
/// [`HostResponse::nodes`].
QueueNodes { ids: Vec<u64> },
/// Stop managed containers hive-wide in one operator action
/// (`hivectl stop`): agents plus the selected infra containers. `scope`
/// (`hivectl stop`): agents plus the gateway when selected. `scope`
/// selects which classes; an all-false scope means **everything** (the
/// bare `hivectl stop`). `graceful` runs the per-agent quiesce (graceful
/// agent stop, issue tracker `graceful agent stop`) instead of a hard
/// stop. Agents stop via the lifecycle path; infra containers via the
/// host `container@<name>` units.
/// stop. Agents stop via the lifecycle path; the gateway via the host
/// `nginx.service` unit.
Stop {
#[serde(default)]
scope: LifecycleScope,
@ -346,17 +346,15 @@ pub struct QuotaRow {
/// [`HostRequest::Start`] touches. An all-false scope means **everything**
/// (the bare `hivectl stop` / `start`); set individual fields to restrict
/// (e.g. only `agents` → just the sub-agent containers). `agents` covers
/// every managed sub-agent container; the rest are the named infra
/// services (`hive-forge`, `hive-gateway`, `hive-matrix`) —
/// containers, bar the gateway, which is the host's nginx unit.
//
// A flat bag of independent flag toggles — one bool per selectable
// container class — is exactly the right shape here: each maps 1:1 to a
// `hivectl` `--forge` / `--gateway` / `--matrix` flag, and they're
// orthogonal (any subset is valid), so a state machine or two-variant enums
// would only obscure the mapping. Hence the `struct_excessive_bools` allow.
#[allow(clippy::struct_excessive_bools)]
/// every managed sub-agent container; `gateway` is the host's nginx unit.
/// The swarm's forge and matrix are not in any scope: a hive does not start
/// or stop them.
///
/// Unknown fields are refused, so a `forge` / `matrix` flag from an older
/// `hivectl` is an error rather than dropped — dropping it would leave an
/// all-false scope, which means everything.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LifecycleScope {
/// All sub-agent containers (`--agents`).
#[serde(default)]
@ -367,11 +365,7 @@ pub struct LifecycleScope {
#[serde(default)]
pub agent_names: Vec<String>,
#[serde(default)]
pub forge: bool,
#[serde(default)]
pub gateway: bool,
#[serde(default)]
pub matrix: bool,
}
impl LifecycleScope {
@ -379,7 +373,7 @@ impl LifecycleScope {
/// classes" (the bare `hivectl stop` / `start` with no scope flags).
#[must_use]
pub fn is_everything(&self) -> bool {
!(self.agents || self.forge || self.gateway || self.matrix) && self.agent_names.is_empty()
!(self.agents || self.gateway) && self.agent_names.is_empty()
}
}