job_queue: hang the approval link off the deploy root

Non-derivable per-node payload rides the node that owns it. Tagging all
four deploy nodes with the approval id would render the same card four
times in `dag_view`.

Also fix `set_queue_step`'s doc comment, which claimed the DAG-id lookup
was exact because approval DAGs are single-node. They are not anymore;
what actually holds is that the chain is strictly sequential with the
root parked in Finishing, so at most one node is ever Running.
This commit is contained in:
atlas 2026-07-25 21:34:22 +02:00 committed by mara
commit 816006fd48
2 changed files with 13 additions and 8 deletions

View file

@ -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<Self>, id: Option<u64>, step: &str) {
let Some(id) = id else { return };
if self.job_queue.set_step_running(id, step) {

View file

@ -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 { .. }) {