jobq-wire: name every outcome, keep the enum spellings, document the schema

Three things, all from review:

Accepted outcomes were built from a hand-listed [Done, Failed, Cancelled,
Skipped] array. Exhaustive today, silently short the day someone adds a
variant — the new outcome would vanish from every edge that accepts it.
BitFlags::ALL asks the type instead.

TerminalState carried rename_all = "snake_case" while its sibling State did
not, so one enum shipped "done" and the other "Done". A rename is a second
spelling of a name that then has to be kept in agreement by hand; both now
serialise their variant names verbatim. Nothing else reads TerminalState off
a wire, so no consumer moves. GraphDep's tag values likewise.

The endpoint documented its body as serde_json::Value, which tells a spec
reader nothing. hive-jobq-wire now derives ToSchema. State and TerminalState
are foreign types here and utoipa stays out of the scheduler crate, so the
schema points at local mirror enums. A mirror that drifts is worse than none:
the conversions are exhaustive (a new upstream variant fails the build) and a
test asserts each documented name equals the serialised one, since an
exhaustive match still compiles when only the spellings diverge.
This commit is contained in:
atlas 2026-08-03 00:14:37 +02:00 committed by mara
commit fe0906c043
5 changed files with 148 additions and 18 deletions

View file

@ -62,10 +62,14 @@ impl NodeId {
/// How a node finished. The terminal subset of [`State`], as its own type so an
/// edge condition cannot name `Pending` / `Running` / `Finishing` — those are
/// meaningless in a dependency and are better unrepresentable than rejected.
///
/// Serialises as its **variant name verbatim** (`"Done"`, `"Cancelled"`), with
/// no `rename_all` transformation — matching [`State`], whose names the
/// dashboard already matches on. A rename is a second spelling of the same
/// value that has to be kept in agreement by hand.
#[enumflags2::bitflags]
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TerminalState {
/// Own logic succeeded and every sub-node did too.
Done,