diff --git a/hive-c0re/src/coordinator.rs b/hive-c0re/src/coordinator.rs index c24247f9..0e78a4d7 100644 --- a/hive-c0re/src/coordinator.rs +++ b/hive-c0re/src/coordinator.rs @@ -668,12 +668,14 @@ impl Coordinator { /// Update the `step` label on the currently-running node of DAG /// `id` and (if it actually changed) re-emit the queue snapshot so - /// the dashboard renders the new phase. DAG-id-only surface for - /// the opaque approval pipeline in `actions.rs`, whose callbacks - /// don't know node ids (its DAGs are single-node, so the lookup is - /// exact); queue executors use the precise per-node sink in - /// `job_queue::exec` instead. No-op when `id` is `None` (callers - /// not running from the queue) or when nothing is `Running`. + /// the dashboard renders the new phase. DAG-id-only surface for the + /// approval-deploy bodies in `actions.rs`, which don't know their node id. + /// The lookup is still exact for them: a deploy DAG is a strictly + /// sequential chain whose resource-holding root sits in `Finishing` while + /// the phases run, so at most one node is ever `Running`. Queue executors + /// that do know their node id use the precise per-node sink in + /// `job_queue::exec` instead. No-op when `id` is `None` (callers not + /// running from the queue) or when nothing is `Running`. pub fn set_queue_step(self: &Arc, id: Option, step: &str) { let Some(id) = id else { return }; if self.job_queue.set_step_running(id, step) { diff --git a/hive-c0re/src/job_queue/mod.rs b/hive-c0re/src/job_queue/mod.rs index b549d8d2..09d90c24 100644 --- a/hive-c0re/src/job_queue/mod.rs +++ b/hive-c0re/src/job_queue/mod.rs @@ -789,8 +789,11 @@ impl QueueInner { Dep::Resource { .. } => None, }) .collect(); - // Non-derivable per-node payload rides the node that owns it. - let approval_id = matches!(node.payload, NodeKind::ApprovalDeploy { .. }) + // Non-derivable per-node payload rides the node that owns it. For a + // deploy that's the subtree root: the phases below it are ordinary + // nodes, and hanging the approval link off all four would render the + // same card four times. + let approval_id = matches!(node.payload, NodeKind::DeployWindow { .. }) .then_some(meta.approval_id) .flatten(); let inputs = if matches!(node.payload, NodeKind::MetaLock { .. }) {