fix(#1953): route approval helper-events to the submitter, not the root agent

This commit is contained in:
damocles 2026-06-23 20:09:40 +02:00 committed by mara
commit 3618399d94
7 changed files with 187 additions and 73 deletions

View file

@ -546,15 +546,18 @@ fn finish_approval(
(ApprovalStatus::Failed, Some(note), false)
}
};
coord.notify_manager(&HelperEvent::ApprovalResolved {
id: approval.id,
agent: approval.agent.clone(),
commit_ref: approval.commit_ref.clone(),
status,
note: note.clone(),
sha: approval.fetched_sha.clone(),
tag: terminal_tag.clone(),
});
coord.notify_submitter(
approval.id,
&HelperEvent::ApprovalResolved {
id: approval.id,
agent: approval.agent.clone(),
commit_ref: approval.commit_ref.clone(),
status,
note: note.clone(),
sha: approval.fetched_sha.clone(),
tag: terminal_tag.clone(),
},
);
// Phase 5b: also fire on the dashboard event channel so the
// browser moves the row out of pending into history without a
// snapshot refetch. `approved` rows that succeed get the
@ -590,37 +593,49 @@ fn finish_approval(
match approval.kind {
ApprovalKind::InitConfig => {
if ok {
coord.notify_manager(&HelperEvent::ConfigReady {
agent: approval.agent.clone(),
});
coord.notify_submitter(
approval.id,
&HelperEvent::ConfigReady {
agent: approval.agent.clone(),
},
);
}
}
ApprovalKind::Spawn => coord.notify_manager(&HelperEvent::Spawned {
agent: approval.agent.clone(),
ok,
note,
sha: approval.fetched_sha.clone(),
}),
ApprovalKind::ApplyCommit if is_first_spawn => {
coord.notify_manager(&HelperEvent::Spawned {
ApprovalKind::Spawn => coord.notify_submitter(
approval.id,
&HelperEvent::Spawned {
agent: approval.agent.clone(),
ok,
note,
sha: approval.fetched_sha.clone(),
});
},
),
ApprovalKind::ApplyCommit if is_first_spawn => {
coord.notify_submitter(
approval.id,
&HelperEvent::Spawned {
agent: approval.agent.clone(),
ok,
note,
sha: approval.fetched_sha.clone(),
},
);
}
// MergeConfigPr ends in a container rebuild just like a
// non-first-spawn ApplyCommit, so both surface the same Rebuilt
// lifecycle event. (MergeConfigPr is never a first spawn — the
// agent already exists — so it never hits the Spawned arm above.)
ApprovalKind::ApplyCommit | ApprovalKind::MergeConfigPr => {
coord.notify_manager(&HelperEvent::Rebuilt {
agent: approval.agent.clone(),
ok,
note,
sha: approval.fetched_sha.clone(),
tag: terminal_tag,
});
coord.notify_submitter(
approval.id,
&HelperEvent::Rebuilt {
agent: approval.agent.clone(),
ok,
note,
sha: approval.fetched_sha.clone(),
tag: terminal_tag,
},
);
}
// UpdateMetaInputs / SchedulePrompt: ApprovalResolved already
// carries the result. No separate lifecycle event needed.
@ -1037,15 +1052,18 @@ pub async fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<()
let sha_short = sha.as_deref().map(|s| s[..s.len().min(12)].to_owned());
let description = a.description.clone();
let agent_owned = a.agent.clone();
coord.notify_manager(&HelperEvent::ApprovalResolved {
id: a.id,
agent: a.agent,
commit_ref: a.commit_ref,
status: ApprovalStatus::Denied,
note: note.map(String::from),
sha,
tag,
});
coord.notify_submitter(
a.id,
&HelperEvent::ApprovalResolved {
id: a.id,
agent: a.agent,
commit_ref: a.commit_ref,
status: ApprovalStatus::Denied,
note: note.map(String::from),
sha,
tag,
},
);
coord.emit_approval_resolved(crate::coordinator::ApprovalResolved {
id,
agent: &agent_owned,