docs(#3255): correct the rest of the relay-shaped wording

mara asked for the docs and comments to be fixed in one PR before the
implementation, since a half-corrected description is what confuses a
reader coming back after a context compact.

Three more places said or implied "forward the payload":

- post_webhook_forge's doc ("relays the delivery to every hive ... the
  payload is never parsed here")
- its OpenAPI request_body description ("the delivery can be relayed
  unmodified") -- this one is published in the spec, so it was the most
  externally visible of them
- DeliveryKind::as_str, which called the hook kind the event's routing
  key; the message is semantic, and which hook it arrived on is an input
  to deriving it rather than the thing sent

docs/swarm/README.md gains the direction next to the interim state, so
"two hooks, one of which only logs" reads as a step rather than a design.
This commit is contained in:
atlas 2026-08-18 12:33:15 +02:00
commit b172e67fbd
2 changed files with 21 additions and 8 deletions

View file

@ -363,6 +363,13 @@ nothing more. **Do not delete either.** Removing a hive's hook stops that
hive acting on knowledge pushes and config PRs; removing the
controller's just gets recreated on its next start.
Where this is going, so the interim state reads as interim: the
controller will **interpret** a delivery and send hives a specific
message — *the knowledge repo changed*, *deploy agent `foo` at rev
`abc123`* — rather than forwarding forge payloads for each hive to
re-derive. Approval happens once, at the swarm level, before the message
is sent; a hive receives a decision, not an event to adjudicate.
Nothing to configure. The hooks are registered only when this host also
serves the swarm UI vhost — that is what publishes the endpoint, and a
hook the forge cannot reach would collect failed deliveries while

View file

@ -218,9 +218,14 @@ impl DeliveryKind {
}
}
/// Stable string form, used for logging and (once fan-out lands) as the
/// event's routing key. Deliberately the same spelling as the path
/// segment so a journal line can be matched against a registered URL.
/// Stable string form, used for logging. Deliberately the same spelling
/// as the path segment so a journal line can be matched against a
/// registered URL.
///
/// ⚠️ **Not the routing key for the swarm→hive message.** That message is
/// semantic (*knowledge repo changed*, *deploy agent X at rev Y*) and is
/// addressed to the hives that need it; which hook a delivery arrived on
/// is an input to deriving it, not the thing sent.
fn as_str(self) -> &'static str {
match self {
Self::Knowledge => "knowledge",
@ -311,9 +316,10 @@ pub(super) fn verify(
/// POST `/webhook/forge/{kind}` — a swarm-wide Forgejo delivery.
///
/// Verifies the HMAC over the raw body, then (once fan-out lands) relays the
/// delivery to every hive over the swarm queue. The payload is never parsed
/// here — see the module docs.
/// Verifies the HMAC over the raw body. Nothing consumes the delivery yet;
/// once the swarm→hive channel lands, this daemon **parses** it and emits a
/// semantic message (*knowledge repo changed*, *deploy agent X at rev Y*) to
/// the hives that need it — see the module docs.
///
/// Returns 200 on an accepted delivery so Forgejo does not retry. A refused
/// one answers 401 (bad signature) or 503 (this daemon has no secret), and
@ -329,8 +335,8 @@ pub(super) fn verify(
content = String,
content_type = "application/json",
description = "Forgejo webhook payload, taken as raw bytes so HMAC \
verification runs over the exact wire bytes and the \
delivery can be relayed unmodified"
verification runs over the exact wire bytes rather \
than over a reserialised copy"
),
responses(
(status = 200, description = "delivery accepted", body = String),