diff --git a/CHANGES.md b/CHANGES.md
index da39722d144..53693725efc 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -51,6 +51,9 @@ default job runner directives for platforms.
### Fixes
+[#4970](https://github.com/cylc/cylc-flow/pull/4970) - Fix handling of suicide
+triggers in back-compat mode.
+
[#4887](https://github.com/cylc/cylc-flow/pull/4887) - Disallow relative paths
in `global.cylc[install]source dirs`.
diff --git a/cylc/flow/task_pool.py b/cylc/flow/task_pool.py
index b9c265747fb..528d33cb5ae 100644
--- a/cylc/flow/task_pool.py
+++ b/cylc/flow/task_pool.py
@@ -1169,8 +1169,9 @@ def spawn_on_output(self, itask, output, forced=False):
self._get_hidden_task_by_id(c_taskid)
or self._get_main_task_by_id(c_taskid)
)
- if c_task is not None:
+ if c_task is not None and c_task != itask:
# Child already exists, update it.
+ # (unless trying to remove itself: a:fail => !a)
self.merge_flows(c_task, itask.flow_nums)
self.workflow_db_mgr.put_insert_task_states(
c_task,
@@ -1181,7 +1182,14 @@ def spawn_on_output(self, itask, output, forced=False):
)
# self.workflow_db_mgr.process_queued_ops()
- elif (itask.flow_nums or forced) and not itask.flow_wait:
+ elif (
+ c_task is None
+ and (itask.flow_nums or forced)
+ and not itask.flow_wait
+ ):
+ # If child is not in the pool already, and parent belongs to a
+ # flow (so it can spawn children), and parent is not waiting
+ # for an upcoming flow merge before spawning ... then spawn it.
c_task = self.spawn_task(
c_name, c_point, itask.flow_nums,
)
diff --git a/cylc/flow/taskdef.py b/cylc/flow/taskdef.py
index 8519629f7c5..8cb94bffcc0 100644
--- a/cylc/flow/taskdef.py
+++ b/cylc/flow/taskdef.py
@@ -291,7 +291,9 @@ def has_only_abs_triggers(self, point):
for trig in dep.task_triggers:
if (
trig.offset_is_absolute or
- trig.offset_is_from_icp
+ trig.offset_is_from_icp or
+ # Don't count self-suicide as a normal trigger.
+ dep.suicide and trig.task_name == self.name
):
has_abs = True
else:
diff --git a/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide.t b/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide.t
new file mode 100644
index 00000000000..d9f79880797
--- /dev/null
+++ b/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide.t
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
+# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#-------------------------------------------------------------------------------
+# Cylc 8 back-compat mode.
+# Test self-induced suicide.
+
+. "$(dirname "$0")/test_header"
+set_test_number 2
+reftest
+exit
diff --git a/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide/reference.log b/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide/reference.log
new file mode 100644
index 00000000000..7a534a2f236
--- /dev/null
+++ b/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide/reference.log
@@ -0,0 +1,2 @@
+1/foo -triggered off [] in flow 1
+1/baz -triggered off ['1/foo'] in flow 1
diff --git a/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide/suite.rc b/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide/suite.rc
new file mode 100644
index 00000000000..c73bead89ae
--- /dev/null
+++ b/tests/functional/spawn-on-demand/16-c7backcompat-self-suicide/suite.rc
@@ -0,0 +1,19 @@
+# suite.rc: Cylc 8 back-compat mode.
+
+# GitHub cylc-flow #4968: self-induced suicide should not retrigger foo below.
+[scheduler]
+ [[events]]
+ stall timeout = PT0S
+ abort on stall timeout = True
+ expected task failures = 1/foo
+[scheduling]
+ [[dependencies]]
+ graph = """
+ foo => bar
+ foo:fail => !foo & !bar
+ foo:fail | bar => baz
+ """
+[runtime]
+ [[foo]]
+ script = false
+ [[bar, baz]]
diff --git a/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling.t b/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling.t
new file mode 100644
index 00000000000..3f5e04d2d6f
--- /dev/null
+++ b/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling.t
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
+# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#-------------------------------------------------------------------------------
+# Cylc 8 back-compat mode.
+# Test self-induced suicide (cycling workflow, absolute triggers).
+
+. "$(dirname "$0")/test_header"
+set_test_number 2
+reftest
+exit
diff --git a/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling/reference.log b/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling/reference.log
new file mode 100644
index 00000000000..bce9543df26
--- /dev/null
+++ b/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling/reference.log
@@ -0,0 +1,3 @@
+1/init -triggered off [] in flow 1
+1/bad -triggered off ['1/init'] in flow 1
+2/bad -triggered off ['1/init'] in flow 1
diff --git a/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling/suite.rc b/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling/suite.rc
new file mode 100644
index 00000000000..1912ff21152
--- /dev/null
+++ b/tests/functional/spawn-on-demand/17-c7backcompat-self-suicide-cycling/suite.rc
@@ -0,0 +1,27 @@
+# suite.rc: Cylc 8 back compat mode.
+
+# GitHub cylc-flow #4968: self-induced suicide in the example below should not
+# cause shutdown after the initial cycle point.
+
+[scheduler]
+ [[events]]
+ stall timeout = PT0S
+ abort on stall timeout = True
+ expected task failures = 1/bad, 2/bad
+[scheduling]
+ cycling mode = integer
+ initial cycle point = 1
+ final cycle point = 2
+ [[dependencies]]
+ [[[R1]]]
+ graph = init
+ [[[P1]]]
+ graph = """
+ init[^] => bad => good
+ bad:fail => !bad & !good
+ """
+[runtime]
+ [[init, good]]
+ script = true
+ [[bad]]
+ script = false