hyperhive/hive-c0re/Cargo.toml
atlas 89050ef34b feat(#3255): hives subscribe to their own knowledge event
A hive learned the knowledge repository had changed only by registering
its own forge webhook. This subscribes to the per-hive subject the
controller now publishes on and calls the pull this daemon already runs
at boot.

Shares the hive's ONE queue connection rather than opening a second: a
second connect would double the auth-callout traffic against authelia and
give the two paths independent reconnect state, so one could be serving
while the other was still down. Same argument as the controller side.

No payload is read, because there is none to read — the webhook handler
this replaces took two fields from Forgejo and used neither, then ran
`git pull`, which re-derives everything from the repository.

At-most-once, and that is not a regression: a webhook delivery to a hive
that is down is lost identically today, and the boot pull covers it.
JetStream would require this end to publish to
`$JS.API.CONSUMER.CREATE.<stream>`, which the callout policy does not
grant, so durability would cost grants on both sides to remove a failure
the boot pull already handles.

⚠️ Documented at the call site rather than left implicit: a refused
subscription is indistinguishable from a quiet one, because NATS reports
authorization violations asynchronously on the connection. If hives stop
hearing events, the server log is the thing that knows.

futures-util comes from the workspace (same version swarm-controller
already uses), not a new dependency version.
2026-08-19 21:05:52 +02:00

66 lines
2.2 KiB
TOML

[package]
name = "hive-c0re"
edition.workspace = true
version.workspace = true
readme = "README.md"
[lints]
workspace = true
[dependencies]
# For `StreamExt::next` on the swarm-event subscription in `swarm_status`.
# Workspace-level, same version swarm-controller already uses — not a second copy.
futures-util.workspace = true
anyhow.workspace = true
# Named directly only for the client type the swarm status publisher passes
# around; the connect itself lives in `swarm-queue-client` below.
async-nats.workspace = true
axum.workspace = true
chrono.workspace = true
base64.workspace = true
bcrypt.workspace = true
reqwest.workspace = true
forgejo-api.workspace = true
url.workspace = true
clap.workspace = true
clap_complete.workspace = true
clap-markdown = "0.1"
# OTEL SDK for the per-agent container-resource metrics exporter
# (stats/otel_metrics.rs). "internal-logs" on top of the workspace base is
# this crate's own opt-in: it's not a transport, it's in `default`, and
# `default-features = false` upstream drops it unless named here.
opentelemetry.workspace = true
opentelemetry_sdk.workspace = true
opentelemetry-otlp = { workspace = true, features = ["internal-logs"] }
indicatif.workspace = true
hive-core-agent-sock.workspace = true
hive-sh4re.workspace = true
hive-host-sock.workspace = true
hive-jobq.workspace = true
hive-jobq-wire.workspace = true
hive-priv-sock.workspace = true
hive-agent-sock.workspace = true
hive-sock-client.workspace = true
hive-types.workspace = true
libc.workspace = true
listenfd = "1"
petgraph.workspace = true
hmac.workspace = true
sha2.workspace = true
rusqlite.workspace = true
serde.workspace = true
serde_json.workspace = true
# Offering this hive's status to the swarm (`swarm_status`). The same crate
# the swarm controller reads it with, and `kv` for the same reason: the
# bucket's name and creation config belong to neither end of it alone.
swarm-queue-client = { workspace = true, features = ["kv"] }
tokio.workspace = true
tokio-stream.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
problem_details = { version = "0.9.0", features = ["axum"] }
utoipa.workspace = true
utoipa-axum.workspace = true
[dev-dependencies]
tempfile = "3"