refactor(#2591): make NodeKind the queue payload — drop JobPayload, agent into variants

This commit is contained in:
atlas 2026-07-20 23:00:20 +02:00 committed by mara
commit be2dfa8cd3
8 changed files with 233 additions and 177 deletions

View file

@ -42,14 +42,14 @@ pub(crate) fn after_ok(on: u64) -> Vec<Dep> {
}]
}
/// Build one **top-level (group-root)** node targeting `agent` — `parent =
/// None`. The single place a node's agent is stamped. Shared with `submit.rs`'s
/// dynamic power-op builders. A root owns whatever resource it declares for its
/// whole subtree; its descendants borrow it (agent-lease / build-slot
/// continuity). Ordering vs other nodes is `deps`; grouping is `parent`.
pub(crate) fn node(agent: &str, kind: NodeKind, deps: Vec<Dep>) -> NodeSpec {
/// Build one **top-level (group-root)** node — `parent = None`. `kind` carries
/// the agent it targets ([`NodeKind`] is the payload directly). Shared with
/// `submit.rs`'s dynamic power-op builders. A root owns whatever resource it
/// declares for its whole subtree; its descendants borrow it (agent-lease /
/// build-slot continuity). Ordering vs other nodes is `deps`; grouping is
/// `parent`.
pub(crate) fn node(kind: NodeKind, deps: Vec<Dep>) -> NodeSpec {
NodeSpec {
agent: agent.to_owned(),
kind,
deps,
parent: None,
@ -60,9 +60,8 @@ pub(crate) fn node(agent: &str, kind: NodeKind, deps: Vec<Dep>) -> NodeSpec {
/// child runs once its parent reaches `Finishing` (the parent gate), so it must
/// NOT `deps` on `parent` (dep-scope validation rejects a dep on one's own
/// parent). `deps` here order the child against its *siblings* only.
pub(crate) fn child(parent: u64, agent: &str, kind: NodeKind, deps: Vec<Dep>) -> NodeSpec {
pub(crate) fn child(parent: u64, kind: NodeKind, deps: Vec<Dep>) -> NodeSpec {
NodeSpec {
agent: agent.to_owned(),
kind,
deps,
parent: Some(parent),
@ -87,22 +86,25 @@ pub(crate) fn child(parent: u64, agent: &str, kind: NodeKind, deps: Vec<Dep>) ->
/// (recovery-start invariant). It takes a fresh lease; the tiny gap is
/// harmless — `Reconcile` converges to the persisted `wanted` idempotently.
pub(crate) fn rebuild_nodes(agent: &str, relock: bool, base: u64) -> Vec<NodeSpec> {
let a = || agent.to_owned();
vec![
node(
agent,
NodeKind::Prebuild { relock },
NodeKind::Prebuild { agent: a(), relock },
if base == 0 {
Vec::new()
} else {
after_ok(base - 1)
},
),
child(base, agent, NodeKind::StopForUpdate, Vec::new()),
child(base + 1, agent, NodeKind::Swap, Vec::new()),
child(base + 1, agent, NodeKind::PostSwap, after_ok(base + 2)),
child(base, NodeKind::StopForUpdate { agent: a() }, Vec::new()),
child(base + 1, NodeKind::Swap { agent: a() }, Vec::new()),
child(
base + 1,
NodeKind::PostSwap { agent: a() },
after_ok(base + 2),
),
node(
agent,
NodeKind::Reconcile,
NodeKind::Reconcile { agent: a() },
vec![Dep {
on: base,
when: DepWhen::AfterAny,
@ -141,7 +143,12 @@ pub fn approval_deploy(agent: &str, approval_id: i64, reason: String) -> DagSpec
inputs: Vec::new(),
perm_payload: None,
transient: Some(TransientKind::Rebuilding),
nodes: vec![node(agent, NodeKind::ApprovalDeploy, Vec::new())],
nodes: vec![node(
NodeKind::ApprovalDeploy {
agent: agent.to_owned(),
},
Vec::new(),
)],
}
}
@ -166,7 +173,12 @@ pub fn reconcile_only(
inputs: Vec::new(),
perm_payload: None,
transient,
nodes: vec![node(agent, NodeKind::Reconcile, Vec::new())],
nodes: vec![node(
NodeKind::Reconcile {
agent: agent.to_owned(),
},
Vec::new(),
)],
}
}
@ -188,12 +200,15 @@ pub fn spawn(agent: &str, approval_id: i64, reason: String) -> DagSpec {
inputs: Vec::new(),
perm_payload: None,
transient: Some(TransientKind::Spawning),
nodes: vec![
node(agent, NodeKind::Provision, Vec::new()),
child(0, agent, NodeKind::Create, Vec::new()),
child(1, agent, NodeKind::WriteDropin, Vec::new()),
child(1, agent, NodeKind::Reconcile, after_ok(2)),
],
nodes: {
let a = || agent.to_owned();
vec![
node(NodeKind::Provision { agent: a() }, Vec::new()),
child(0, NodeKind::Create { agent: a() }, Vec::new()),
child(1, NodeKind::WriteDropin { agent: a() }, Vec::new()),
child(1, NodeKind::Reconcile { agent: a() }, after_ok(2)),
]
},
}
}
@ -201,7 +216,12 @@ pub fn spawn(agent: &str, approval_id: i64, reason: String) -> DagSpec {
/// the updated `HIVE_TOOL_GROUPS` / `HIVE_CAPABILITIES` env var takes
/// effect in the container.
pub fn perm_change(agent: &str, source: Source, reason: String, payload: PermPayload) -> DagSpec {
let mut nodes = vec![node(agent, NodeKind::WritePermFile, Vec::new())];
let mut nodes = vec![node(
NodeKind::WritePermFile {
agent: agent.to_owned(),
},
Vec::new(),
)];
nodes.extend(rebuild_nodes(agent, true, 1));
DagSpec {
template: Template::PermChange,
@ -240,7 +260,6 @@ pub fn meta_update(
perm_payload: None,
transient: Some(TransientKind::Rebuilding),
nodes: vec![node(
"hyperhive",
NodeKind::MetaLock {
sweep: false,
fanout: None,