[package] name = "swarm-controller" version.workspace = true readme = "README.md" edition.workspace = true [[bin]] name = "swarm-controller" path = "src/main.rs" [dependencies] anyhow.workspace = true # `kv` (which pulls `jetstream`) on top of the workspace's feature set: the # queue is this daemon's *store*, not just its transport - a hive's last # status snapshot is read out of a JetStream KV bucket. Declared here rather # than in the workspace entry so the auth-callout responder, which speaks # neither, does not claim to need them. async-nats = { workspace = true, features = ["kv"] } axum.workspace = true # swarm-controller's own forge client (`forge.rs`) — self-contained, # deliberately not sharing code with `hive-c0re::forge` across the crate # boundary (see #3306's design discussion: forcing that split now, over a # few idempotent CRUD-ish calls, is premature plumbing). forgejo-api.workspace = true # Only for base64-encoding file content for `forge.rs`'s # `repo_change_files` calls — forgejo's content API takes base64, never # raw bytes. base64.workspace = true futures-util.workspace = true # RFC 9457 `application/problem+json` error bodies. Same version + `axum` # feature as hive-c0re: the two daemons answer the same operator UIs, so a # reader that handles one's failures has to handle the other's. problem_details = { version = "0.9.0", features = ["axum"] } # The graph itself, held directly rather than behind a c0re-style wrapper # module — that layering (`hive-c0re::job_queue`) is partially legacy (predates # `hive-jobq`'s extraction into its own crate) and this daemon does not need it # repeated. Driven by `hive_jobq::scheduler::Scheduler` (`spawn_jobq_worker`), # same shape `hive-c0re/src/job_queue/scheduler.rs` uses over its own graph. hive-jobq.workspace = true hive-jobq-wire.workspace = true # The jobq-rollup OTEL exporter, wired up in `main` via # `hive_jobq_metrics::spawn_exporter` — moved to its own crate (rather than # living here as `jobq_metrics.rs`) specifically so a future second caller # (e.g. hive-c0re, for its own per-hive job graph) doesn't have to depend on # this whole binary to reuse it. hive-jobq-metrics.workspace = true # Direct OTEL SDK use in `vcs_metrics.rs` — sync counters recorded off # webhook deliveries, a different shape from `hive-jobq-metrics`'s # observable-gauge rollup, so it isn't a fit for that crate's API and lives # here instead. Same three crates that pairing already pulls in transitively, # named directly since this module builds its own `SdkMeterProvider`. opentelemetry.workspace = true opentelemetry_sdk.workspace = true opentelemetry-otlp.workspace = true # The forge webhook HMAC (`webhook.rs`). Kept in this crate rather than # shared with hive-c0re's equivalent: c0re's copy is scheduled to be deleted # with its webhook routes once registration moves here, so the second holder # is departing, not arriving — see that module's docs. hmac.workspace = true sha2.workspace = true # Validates `POST /api/agents`' `name` before it becomes `agent`/`repo` # everywhere downstream — see `create_agent`'s doc comment for why this is # defense-in-depth, not the only gate (per an argus review finding). hive-types.workspace = true # `auth`'s bridge client — same crate the bridge itself uses to define the # request/response shape, so the two ends cannot drift. `forge.rs` also # uses this directly for `StatusCode` in its error-classification helpers. reqwest.workspace = true serde.workspace = true serde_json.workspace = true swarm-authelia-bridge-sock.workspace = true # The queue connect (token mint + auth callback + reconnect) is shared with # every other participant - a hive publishing its own status runs the same # code with a different client id. Two copies of credential handling is one # token-refresh fix that has to be found twice. # # `kv` for the same reason one level in: the status bucket's name and # creation config are shared with the hive that writes it, so this end does # not get to declare them privately. swarm-queue-client = { workspace = true, features = ["kv"] } tokio.workspace = true tracing.workspace = true tracing-subscriber.workspace = true url.workspace = true utoipa.workspace = true utoipa-axum.workspace = true [lints] workspace = true