hive-c0re: drop redundant METHOD/path prefixes from OpenAPI summaries

Swagger UI's endpoint-list row already shows the HTTP method badge +
path for every row, so restating `METHOD /path` at the start of a
handler's own summary is pure duplication. Strips that self-referential
prefix from every summary that has it and re-capitalizes what follows
as a standalone sentence.

Left two false positives untouched: misc_api.rs's operator-inbox
summary cross-references a *different* sibling endpoint
(mark-all-read) for context, and topology.rs's SetParentForm struct
doc happens to mention its endpoint's path but isn't a handler summary
line. Both are legitimate, not redundant.
This commit is contained in:
iris 2026-08-02 21:03:33 +02:00 committed by mara
commit ec30277a90
16 changed files with 49 additions and 49 deletions

View file

@ -16,7 +16,7 @@ use super::{AppState, error_response};
use crate::actions; use crate::actions;
use crate::coordinator::Coordinator; use crate::coordinator::Coordinator;
/// `POST /api/approve/{id}` — approve a pending approval row. /// Approve a pending approval row.
#[utoipa::path( #[utoipa::path(
post, post,
path = "/api/approve/{id}", path = "/api/approve/{id}",
@ -47,7 +47,7 @@ pub(super) struct DenyForm {
note: Option<String>, note: Option<String>,
} }
/// `POST /api/deny/{id}` — deny a pending approval row, with an optional /// Deny a pending approval row, with an optional
/// note (form field `note`). /// note (form field `note`).
#[utoipa::path( #[utoipa::path(
post, post,

View file

@ -29,7 +29,7 @@ pub(super) struct BuildLogsAllQuery {
limit: Option<usize>, limit: Option<usize>,
} }
/// `GET /api/build-logs?limit=N` — most-recent build log headers across /// Most-recent build log headers across
/// all agents, newest first. /// all agents, newest first.
/// ///
/// Same JSON shape as the per-agent endpoint. /// Same JSON shape as the per-agent endpoint.
@ -62,7 +62,7 @@ pub(super) struct BuildLogsQuery {
limit: Option<usize>, limit: Option<usize>,
} }
/// `GET /api/build-logs/{agent}?limit=N` — most-recent build log /// Most-recent build log
/// headers for one agent, newest first. /// headers for one agent, newest first.
/// ///
/// Returns `Vec<BuildLogHeader>` (JSON). Backs the per-agent log chip /// Returns `Vec<BuildLogHeader>` (JSON). Backs the per-agent log chip
@ -103,7 +103,7 @@ pub(super) async fn get_build_logs_agent(
} }
} }
/// `GET /api/build-logs/id/{id}` — full build log row (stdout + /// Full build log row (stdout +
/// stderr concatenated) by id. /// stderr concatenated) by id.
/// ///
/// Returns `BuildLogFull` (JSON), or HTTP 404 when the id doesn't /// Returns `BuildLogFull` (JSON), or HTTP 404 when the id doesn't
@ -131,7 +131,7 @@ pub(super) async fn get_build_log_full(
} }
} }
/// `GET /api/build-log/{node_id}` — the build log for a **queue node**, /// The build log for a **queue node**,
/// resolved node id → log-row id → full log. /// resolved node id → log-row id → full log.
/// ///
/// Same `BuildLogFull` JSON (`stdout` / `stderr` + header) as /// Same `BuildLogFull` JSON (`stdout` / `stderr` + header) as
@ -166,7 +166,7 @@ pub(super) async fn get_build_log_for_node(
} }
} }
/// `GET /api/build-log/{node_id}/raw` — the node's build log as `text/plain` /// The node's build log as `text/plain`
/// for download (delegates to `get_build_log_raw` after resolving the node id). /// for download (delegates to `get_build_log_raw` after resolving the node id).
#[utoipa::path( #[utoipa::path(
get, get,
@ -206,7 +206,7 @@ struct BuildLogFrame {
done: bool, done: bool,
} }
/// `GET /api/build-logs/id/{id}/stream` — SSE stream that delivers /// SSE stream that delivers
/// incremental stdout/stderr as a build runs. /// incremental stdout/stderr as a build runs.
/// ///
/// The client connects when it opens a running-build panel; the /// The client connects when it opens a running-build panel; the
@ -314,7 +314,7 @@ pub(super) async fn get_build_log_stream(
Sse::new(ReceiverStream::new(rx)).keep_alive(KeepAlive::default()) Sse::new(ReceiverStream::new(rx)).keep_alive(KeepAlive::default())
} }
/// `GET /api/build-logs/id/{id}/raw` — full log as `text/plain` for /// Full log as `text/plain` for
/// download. /// download.
/// ///
/// Stdout and stderr are concatenated with a `--- stderr ---` /// Stdout and stderr are concatenated with a `--- stderr ---`

View file

@ -58,7 +58,7 @@ pub(super) struct ExtraForgesQuery {
agent: String, agent: String,
} }
/// `GET /api/extra-forges?agent=<name>` — list the external forge /// List the external forge
/// accounts currently provisioned for `agent`. /// accounts currently provisioned for `agent`.
/// ///
/// Derived from every `forge-<label>-token` file in its state dir /// Derived from every `forge-<label>-token` file in its state dir
@ -135,7 +135,7 @@ struct ExtraForgeAccountResult {
ok: bool, ok: bool,
} }
/// `POST /api/extra-forge-account` — add persists the operator-pasted /// Add persists the operator-pasted
/// label/base-URL/token to the agent's state dir via hive-priv; remove /// label/base-URL/token to the agent's state dir via hive-priv; remove
/// deletes both files. /// deletes both files.
/// ///

View file

@ -28,7 +28,7 @@ use utoipa::ToSchema;
use crate::host_stats::ServerWarning; use crate::host_stats::ServerWarning;
/// `GET /health/live` — liveness. Always `200`; no further checks. /// Liveness. Always `200`; no further checks.
#[utoipa::path( #[utoipa::path(
get, get,
path = "/health/live", path = "/health/live",
@ -49,7 +49,7 @@ struct ReadyBody {
warnings: Vec<ServerWarning>, warnings: Vec<ServerWarning>,
} }
/// `GET /health/ready` — readiness. /// Readiness.
/// ///
/// `200` with `{"status":"ok", "warnings": [...]}` unless a `crit`-level /// `200` with `{"status":"ok", "warnings": [...]}` unless a `crit`-level
/// warning is currently set in [`crate::warnings::snapshot`], in which /// warning is currently set in [`crate::warnings::snapshot`], in which

View file

@ -14,7 +14,7 @@ use hive_priv_sock::{InfraAction, InfraContainer};
use super::{AppState, error_response}; use super::{AppState, error_response};
/// `POST /api/infra-container/{name}/{action}` — start / stop / restart a /// Start / stop / restart a
/// hive infrastructure container from the dashboard. /// hive infrastructure container from the dashboard.
/// ///
/// `name` parses into [`InfraContainer`] (the allowlist; unrecognised /// `name` parses into [`InfraContainer`] (the allowlist; unrecognised

View file

@ -160,7 +160,7 @@ pub(super) struct JournalHostQuery {
lines: Option<u32>, lines: Option<u32>,
} }
/// `GET /api/journal-host?unit=<unit>&lines=N` — host-side journald (no /// Host-side journald (no
/// `-M` container flag). /// `-M` container flag).
/// ///
/// Restricted to an allow-list of known host services so arbitrary unit /// Restricted to an allow-list of known host services so arbitrary unit

View file

@ -30,7 +30,7 @@ use super::{AppState, Ident, error_response, guard_agent_name, strip_container_p
use crate::job_queue::{Source, submit}; use crate::job_queue::{Source, submit};
use crate::{actions, lifecycle}; use crate::{actions, lifecycle};
/// `POST /api/rebuild/{name}` — queue a rebuild DAG for `name`. /// Queue a rebuild DAG for `name`.
#[utoipa::path( #[utoipa::path(
post, post,
path = "/api/rebuild/{name}", path = "/api/rebuild/{name}",
@ -59,7 +59,7 @@ pub(super) async fn post_rebuild(
(StatusCode::OK, "ok").into_response() (StatusCode::OK, "ok").into_response()
} }
/// `POST /api/kill/{name}?graceful=1` — stop `name`, hard by default or /// Stop `name`, hard by default or
/// gracefully when `graceful=1`. /// gracefully when `graceful=1`.
/// ///
/// Graceful mode: quiesce → drain → stop. /// Graceful mode: quiesce → drain → stop.
@ -121,7 +121,7 @@ pub(super) async fn post_kill(
(StatusCode::OK, "ok").into_response() (StatusCode::OK, "ok").into_response()
} }
/// `POST /api/restart/{name}?graceful=1` — restart `name`, hard by default /// Restart `name`, hard by default
/// or gracefully when `graceful=1`. /// or gracefully when `graceful=1`.
/// ///
/// Graceful mode: quiesce → drain → restart. /// Graceful mode: quiesce → drain → restart.
@ -176,7 +176,7 @@ pub(super) struct StartParams {
paused: bool, paused: bool,
} }
/// `POST /api/start/{name}?paused=1` — start `name`, optionally paused. /// Start `name`, optionally paused.
/// ///
/// Plain `?paused=1` mirrors `hivectl agent <name> start --paused`: if /// Plain `?paused=1` mirrors `hivectl agent <name> start --paused`: if
/// `name` is already running, this just writes the pause marker in place /// `name` is already running, this just writes the pause marker in place
@ -236,7 +236,7 @@ pub(super) async fn post_start(
(StatusCode::OK, "ok").into_response() (StatusCode::OK, "ok").into_response()
} }
/// `POST /api/pause/{name}` — write the pause marker for `name`. /// Write the pause marker for `name`.
/// ///
/// Unlike the lifecycle ops above this is not a DAG: it writes a single /// Unlike the lifecycle ops above this is not a DAG: it writes a single
/// marker file, which the harness stats at the top of its serve loop. /// marker file, which the harness stats at the top of its serve loop.
@ -275,7 +275,7 @@ pub(super) async fn post_pause(
(StatusCode::OK, "ok").into_response() (StatusCode::OK, "ok").into_response()
} }
/// `POST /api/resume/{name}` — remove the pause marker for `name`. /// Remove the pause marker for `name`.
/// ///
/// The inverse of `post_pause`. Removing a non-existent marker is a no-op /// The inverse of `post_pause`. Removing a non-existent marker is a no-op
/// (idempotent). Triggers an immediate rescan so the paused badge clears. /// (idempotent). Triggers an immediate rescan so the paused badge clears.
@ -321,7 +321,7 @@ pub(super) struct ResourceLimitsForm {
memory_max: String, memory_max: String,
} }
/// `POST /api/resource-limits/{name}` — write per-agent CPU/memory limit /// Write per-agent CPU/memory limit
/// overrides for `name`. /// overrides for `name`.
/// ///
/// An empty `cpu_quota` or `memory_max` field clears that field's override, /// An empty `cpu_quota` or `memory_max` field clears that field's override,
@ -394,7 +394,7 @@ pub(super) async fn post_resource_limits(
(StatusCode::OK, "ok").into_response() (StatusCode::OK, "ok").into_response()
} }
/// `POST /api/update-all` — queue a rebuild DAG for every live agent /// Queue a rebuild DAG for every live agent
/// container. /// container.
#[utoipa::path( #[utoipa::path(
post, post,
@ -427,7 +427,7 @@ pub(super) struct DestroyForm {
purge: Option<String>, purge: Option<String>,
} }
/// `POST /api/destroy/{name}` — destroy `name`'s container. /// Destroy `name`'s container.
/// ///
/// Form field `purge` (any non-empty value, e.g. `"on"`) also wipes the /// Form field `purge` (any non-empty value, e.g. `"on"`) also wipes the
/// retained state dir instead of leaving a tombstone. /// retained state dir instead of leaving a tombstone.

View file

@ -103,7 +103,7 @@ fn account_name_from_filename(fname: &str) -> Option<String> {
Some(suffix.to_owned()) Some(suffix.to_owned())
} }
/// `GET /api/matrix-accounts?agent=<name>` — matrix accounts provisioned /// Matrix accounts provisioned
/// for `agent`. /// for `agent`.
/// ///
/// Backfilled with `homeserver`/`live`/`user_id` from the daemon's /// Backfilled with `homeserver`/`live`/`user_id` from the daemon's
@ -343,7 +343,7 @@ struct GithubAccountStatus {
present: bool, present: bool,
} }
/// `GET /api/github-account?agent=<name>` — whether the agent has a GitHub /// Whether the agent has a GitHub
/// PAT provisioned (its `github-token` file exists). /// PAT provisioned (its `github-token` file exists).
/// ///
/// Lets the credentials tab show "token stored" vs "not set" instead of a /// Lets the credentials tab show "token stored" vs "not set" instead of a

View file

@ -114,7 +114,7 @@ pub(super) async fn api_container_resources() -> Response {
axum::Json(crate::container_stats::gather().await).into_response() axum::Json(crate::container_stats::gather().await).into_response()
} }
/// `GET /api/audit-log` — most-recent agent-initiated privileged-action /// Most-recent agent-initiated privileged-action
/// audit entries, newest first (server-clamped to 500). /// audit entries, newest first (server-clamped to 500).
/// ///
/// Backs the operator dashboard's audit view. Returns /// Backs the operator dashboard's audit view. Returns
@ -193,7 +193,7 @@ pub(super) struct OpSendForm {
body: String, body: String,
} }
/// `POST /api/op-send` — operator compose: drop a message into the /// Operator compose: drop a message into the
/// broker addressed to `to` (or `*` to broadcast). /// broker addressed to `to` (or `*` to broadcast).
#[utoipa::path( #[utoipa::path(
post, post,
@ -249,7 +249,7 @@ pub(super) struct RequestSpawnForm {
name: String, name: String,
} }
/// `POST /api/request-spawn` — queue a spawn approval for `name`. /// Queue a spawn approval for `name`.
#[utoipa::path( #[utoipa::path(
post, post,
path = "/api/request-spawn", path = "/api/request-spawn",

View file

@ -37,7 +37,7 @@ pub(super) struct ToolGroupsSnapshot {
effective: std::collections::BTreeMap<String, Vec<String>>, effective: std::collections::BTreeMap<String, Vec<String>>,
} }
/// `GET /api/tool-groups` — every known tool-group name + description, /// Every known tool-group name + description,
/// plus the per-agent explicit/effective assignment maps. /// plus the per-agent explicit/effective assignment maps.
#[utoipa::path( #[utoipa::path(
get, get,
@ -119,7 +119,7 @@ pub(super) struct SetToolGroupsBody {
groups: Vec<String>, groups: Vec<String>,
} }
/// `POST /api/tool-groups/{agent}` — replace `agent`'s explicit tool-group /// Replace `agent`'s explicit tool-group
/// assignment (JSON body `{"groups": [...]}`). /// assignment (JSON body `{"groups": [...]}`).
#[utoipa::path( #[utoipa::path(
post, post,
@ -187,7 +187,7 @@ pub(super) struct CapabilitiesSnapshot {
effective: std::collections::BTreeMap<String, Vec<String>>, effective: std::collections::BTreeMap<String, Vec<String>>,
} }
/// `GET /api/capabilities` — every known capability name + description, /// Every known capability name + description,
/// plus the per-agent explicit/effective grant maps. /// plus the per-agent explicit/effective grant maps.
#[utoipa::path( #[utoipa::path(
get, get,
@ -227,7 +227,7 @@ pub(super) struct SetCapabilitiesBody {
caps: Vec<String>, caps: Vec<String>,
} }
/// `POST /api/capabilities/{agent}` — replace `agent`'s explicit capability /// Replace `agent`'s explicit capability
/// grant set (JSON body `{"caps": [...]}`). /// grant set (JSON body `{"caps": [...]}`).
#[utoipa::path( #[utoipa::path(
post, post,
@ -383,7 +383,7 @@ pub(super) struct StalePermsResponse {
stale: Vec<String>, stale: Vec<String>,
} }
/// `GET /api/permissions/stale` — agent names with explicit permission /// Agent names with explicit permission
/// entries but no matching live container or kept-state dir. /// entries but no matching live container or kept-state dir.
#[utoipa::path( #[utoipa::path(
get, get,

View file

@ -38,7 +38,7 @@ fn with_cors(resp: impl IntoResponse) -> Response {
resp resp
} }
/// `POST /answer-question/{id}` — record the operator's answer and /// Record the operator's answer and
/// notify the asker. /// notify the asker.
#[utoipa::path( #[utoipa::path(
post, post,
@ -94,7 +94,7 @@ pub(super) async fn post_answer_question(
with_cors(resp) with_cors(resp)
} }
/// `POST /cancel-question/{id}` — resolve a pending question with the /// Resolve a pending question with the
/// `[cancelled]` sentinel answer. /// `[cancelled]` sentinel answer.
/// ///
/// Used when the operator decides not to / can't answer. The asker /// Used when the operator decides not to / can't answer. The asker

View file

@ -18,7 +18,7 @@ use crate::scheduled_prompts_worker::FireNowReport;
use super::{AppState, error_problem, error_response}; use super::{AppState, error_problem, error_response};
/// `GET /api/schedules` — snapshot of every schedule for the /// Snapshot of every schedule for the
/// scheduled-prompts tab. /// scheduled-prompts tab.
/// ///
/// Returns the wire shape directly so the frontend can render /// Returns the wire shape directly so the frontend can render
@ -59,7 +59,7 @@ pub(super) async fn api_schedules(State(state): State<AppState>) -> Response {
} }
} }
/// `POST /api/schedules` — operator-direct schedule creation /// Operator-direct schedule creation
/// (mara: "user can add them manually"). /// (mara: "user can add them manually").
/// ///
/// Accepts the same `SchedulePromptPayload` shape as the manager /// Accepts the same `SchedulePromptPayload` shape as the manager
@ -122,7 +122,7 @@ pub(super) struct FireNowBody {
reset_timer: bool, reset_timer: bool,
} }
/// `POST /api/schedules/{id}/fire-now` — operator-initiated /// Operator-initiated
/// out-of-band fire of a scheduled prompt. /// out-of-band fire of a scheduled prompt.
/// ///
/// Runs the per-target fan-out once immediately and reports /// Runs the per-target fan-out once immediately and reports
@ -158,7 +158,7 @@ pub(super) async fn post_schedule_fire_now(
} }
} }
/// `POST /api/rebuild-queue/{id}/cancel` — drop still-queued work from the job /// Drop still-queued work from the job
/// queue. /// queue.
/// ///
/// `id` is a **node** id. A DAG's root cancels the whole group (the scheduler /// `id` is a **node** id. A DAG's root cancels the whole group (the scheduler
@ -248,7 +248,7 @@ where
T::deserialize(deserializer).map(Some) T::deserialize(deserializer).map(Some)
} }
/// `PATCH /api/schedules/{id}` — partial update of an existing /// Partial update of an existing
/// schedule. /// schedule.
/// ///
/// Mutable fields: `body`, `description`, `interval_seconds`, /// Mutable fields: `body`, `description`, `interval_seconds`,
@ -299,7 +299,7 @@ pub(super) async fn patch_schedule(
} }
} }
/// `POST /api/schedules/{id}/pause` — pause a schedule so the worker /// Pause a schedule so the worker
/// skips it until explicitly resumed. /// skips it until explicitly resumed.
/// ///
/// Idempotent; no-op on an already-paused row. Returns 404 when the /// Idempotent; no-op on an already-paused row. Returns 404 when the
@ -334,7 +334,7 @@ pub(super) async fn post_schedule_pause(
} }
} }
/// `POST /api/schedules/{id}/resume` — resume a paused schedule. /// Resume a paused schedule.
/// ///
/// Idempotent; no-op on an already-active row. Returns 404 when the /// Idempotent; no-op on an already-active row. Returns 404 when the
/// schedule is cancelled or not found. /// schedule is cancelled or not found.
@ -368,7 +368,7 @@ pub(super) async fn post_schedule_resume(
} }
} }
/// `POST /api/schedules/{id}/cancel` — operator-side cancel /// Operator-side cancel
/// (whole schedule when no `targets` field, partial when one is /// (whole schedule when no `targets` field, partial when one is
/// provided). /// provided).
/// ///

View file

@ -167,7 +167,7 @@ pub fn scan_validated_paths(body: &str) -> Vec<String> {
out out
} }
/// `GET /api/state-file?path=…` — serve an allow-listed file. /// Serve an allow-listed file.
/// ///
/// Raster images get their real content-type; everything else is /// Raster images get their real content-type; everything else is
/// served as (possibly truncated) text. /// served as (possibly truncated) text.

View file

@ -293,7 +293,7 @@ where
/// minutes. /// minutes.
const CRASH_WARNING_WINDOW: std::time::Duration = std::time::Duration::from_mins(10); const CRASH_WARNING_WINDOW: std::time::Duration = std::time::Duration::from_mins(10);
/// `GET /api/state` — cold-load snapshot of the whole dashboard. /// Cold-load snapshot of the whole dashboard.
/// ///
/// Includes the roster, approvals (+ history), questions (+ history), /// Includes the roster, approvals (+ history), questions (+ history),
/// tombstones, job queue, meta inputs, and more. Live clients then /// tombstones, job queue, meta inputs, and more. Live clients then

View file

@ -104,7 +104,7 @@ pub(crate) async fn emit_tombstones_snapshot(coord: &Arc<Coordinator>) {
}); });
} }
/// `POST /api/purge-tombstone/{name}` — wipe a tombstoned agent's /// Wipe a tombstoned agent's
/// retained state dir + applied config dir entirely. /// retained state dir + applied config dir entirely.
#[utoipa::path( #[utoipa::path(
post, post,

View file

@ -47,7 +47,7 @@ pub(super) struct SetParentBulkEntry {
new_parent: Option<String>, new_parent: Option<String>,
} }
/// `POST /api/topology/set-parent` — operator-driven parent move. /// Operator-driven parent move.
/// ///
/// Form fields: `child` (required, agent name), `new_parent` /// Form fields: `child` (required, agent name), `new_parent`
/// (optional — empty / absent string ⇒ promote to root). Refuses /// (optional — empty / absent string ⇒ promote to root). Refuses
@ -103,7 +103,7 @@ pub(super) async fn post_set_parent(
Ok((StatusCode::OK, "ok").into_response()) Ok((StatusCode::OK, "ok").into_response())
} }
/// `POST /api/topology/set-parent-bulk` — move multiple agents in a /// Move multiple agents in a
/// single request, producing **one** git commit. /// single request, producing **one** git commit.
/// ///
/// JSON body: `[{"child":"name", "new_parent":"target-or-null"}, ...]`. /// JSON body: `[{"child":"name", "new_parent":"target-or-null"}, ...]`.