huskies: merge 1235 bug Notifications fire off the filesystem watcher, not the state machine — story 995's TransitionFired subscriber was never wired into startup

This commit is contained in:
Huskies Agent
2026-07-20 14:36:49 +00:00
parent f7b7f21e88
commit 30ca3ad463
2 changed files with 19 additions and 28 deletions
+16 -1
View File
@@ -361,8 +361,23 @@ pub async fn run_bot(
let notif_room_id_strings: Vec<String> = notif_room_ids.iter().map(|r| r.to_string()).collect();
crate::service::notifications::spawn_notification_listener(
Arc::clone(&transport),
move || notif_room_id_strings.clone(),
{
let notif_room_id_strings = notif_room_id_strings.clone();
move || notif_room_id_strings.clone()
},
watcher_rx,
notif_project_root.clone(),
);
// Spawn the TransitionFired-driven stage-notification subscriber (story
// 995) here too — this was previously only wired for WhatsApp/Slack/Discord
// (`startup::bots::spawn_notification_listeners`), leaving Matrix
// deployments with no stage-transition chat notifications at all (story
// 1235). Spawned once here, before the sync loop below, so the task runs
// independently of Matrix sync reconnects/re-logins.
crate::service::notifications::spawn_stage_notification_subscriber(
Arc::clone(&transport),
move || notif_room_id_strings.clone(),
notif_project_root,
);
+3 -27
View File
@@ -50,9 +50,9 @@ pub enum EventAction {
/// Classify a [`WatcherEvent`] into the action the notification listener should take.
pub fn classify(event: &WatcherEvent) -> EventAction {
match event {
// Stage-change notifications are now handled by the TransitionFired subscriber
// (story 995). WorkItem events are skipped regardless of from_stage.
WatcherEvent::WorkItem { .. } => EventAction::Skip,
// Stage-change notifications are handled by the TransitionFired
// subscriber (story 995/1235), not this watcher-event path — WorkItem
// falls through to the `_` catch-all below.
WatcherEvent::MergeFailure { .. } => EventAction::MergeFailure,
WatcherEvent::RateLimitWarning { .. } => EventAction::RateLimitWarning,
WatcherEvent::StoryBlocked { .. } => EventAction::StoryBlocked,
@@ -79,30 +79,6 @@ pub fn classify(event: &WatcherEvent) -> EventAction {
mod tests {
use super::*;
fn work_item(from_stage: Option<&str>) -> WatcherEvent {
WatcherEvent::WorkItem {
stage: "3_qa".to_string(),
item_id: "1_story_foo".to_string(),
action: "qa".to_string(),
commit_msg: String::new(),
from_stage: from_stage.map(str::to_string),
}
}
// Stage-change notifications moved to TransitionFired subscriber (story 995).
// All WorkItem events are now classified as Skip regardless of from_stage.
#[test]
fn work_item_with_from_stage_is_skip() {
let event = work_item(Some("2_current"));
assert_eq!(classify(&event), EventAction::Skip);
}
#[test]
fn work_item_without_from_stage_is_skip() {
let event = work_item(None);
assert_eq!(classify(&event), EventAction::Skip);
}
#[test]
fn merge_failure_is_classified_correctly() {
let event = WatcherEvent::MergeFailure {