From c652526d4b2696f983973f4adfbe8263572739d0 Mon Sep 17 00:00:00 2001 From: Hilary James Oliver Date: Thu, 26 Mar 2026 09:26:23 +1300 Subject: [PATCH 1/4] Add future final-incomplete tasks to n=0 for visibility. --- cylc/flow/task_pool.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cylc/flow/task_pool.py b/cylc/flow/task_pool.py index 8397696d01..79b409c496 100644 --- a/cylc/flow/task_pool.py +++ b/cylc/flow/task_pool.py @@ -2255,6 +2255,15 @@ def _set_outputs_itask( itask.state_reset(is_runahead=False, is_queued=False) self.task_queue_mgr.remove_task(itask) + if ( + itask.state(*TASK_STATUSES_FINAL) + and not itask.state.outputs.is_complete() + ): + # Add future final-incomplete tasks to the pool for visibility. + # (See https://github.com/cylc/cylc-flow/issues/6383). + self.add_to_pool(itask) + LOG.debug(f"[{itask}] adding future incomplete task to n=0.") + if no_op: return False From eed2790cfd5d3e92500d00b3453b27c6eefb4df2 Mon Sep 17 00:00:00 2001 From: Hilary James Oliver Date: Thu, 26 Mar 2026 09:47:28 +1300 Subject: [PATCH 2/4] Extend an integration test. --- tests/integration/test_task_pool.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_task_pool.py b/tests/integration/test_task_pool.py index 653122b1d6..0aa6d0b37f 100644 --- a/tests/integration/test_task_pool.py +++ b/tests/integration/test_task_pool.py @@ -1496,7 +1496,10 @@ async def test_set_outputs_future( { 'scheduling': { 'graph': { - 'R1': "a:x & a:y => b => c" + 'R1': """ + a:x & a:y => b => c + a:y => f + """ } }, 'runtime': { @@ -1521,6 +1524,12 @@ async def test_set_outputs_future( {TaskTokens('1', 'b')}, ["succeeded"], [], []) assert schd.pool.get_task_ids() == {"1/a", "1/c"} + # setting inactive task f failed should add it to n=0 as final + # incomplete - see https://github.com/cylc/cylc-flow/pull/7248 + schd.pool.set_prereqs_and_outputs( + {TaskTokens('1', 'f')}, ["failed"], [], []) + assert schd.pool.get_task_ids() == {"1/a", "1/c", "1/f"} + schd.pool.set_prereqs_and_outputs( items={TaskTokens('1', 'a')}, outputs=["x", "y", "cheese"], From d3b0d675f0d476d4c768e543d22b2c5344c5d90f Mon Sep 17 00:00:00 2001 From: Hilary James Oliver Date: Thu, 26 Mar 2026 09:53:44 +1300 Subject: [PATCH 3/4] Update change log. --- changes.d/7248.feat.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes.d/7248.feat.md diff --git a/changes.d/7248.feat.md b/changes.d/7248.feat.md new file mode 100644 index 0000000000..5d41bafb5c --- /dev/null +++ b/changes.d/7248.feat.md @@ -0,0 +1 @@ +Spawn future final-incomplete tasks into n=0 for visibility. From d8ffb7fa475854cc51c28464b43090608115113d Mon Sep 17 00:00:00 2001 From: Hilary James Oliver Date: Wed, 29 Jul 2026 02:10:56 +0000 Subject: [PATCH 4/4] Spawn next parentless if adding future task to pool. --- cylc/flow/task_pool.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cylc/flow/task_pool.py b/cylc/flow/task_pool.py index 79b409c496..78d56b678f 100644 --- a/cylc/flow/task_pool.py +++ b/cylc/flow/task_pool.py @@ -2254,15 +2254,21 @@ def _set_outputs_itask( # Can't be runahead limited or queued. itask.state_reset(is_runahead=False, is_queued=False) self.task_queue_mgr.remove_task(itask) + # If we skipped over runahead release and this tasks parentless + # it's next parentless instance might need to be spawned. + if itask.flow_nums and not itask.is_xtrigger_sequential: + self.spawn_next_parentless(itask) if ( itask.state(*TASK_STATUSES_FINAL) and not itask.state.outputs.is_complete() ): # Add future final-incomplete tasks to the pool for visibility. - # (See https://github.com/cylc/cylc-flow/issues/6383). - self.add_to_pool(itask) + # See https://github.com/cylc/cylc-flow/issues/6383. LOG.debug(f"[{itask}] adding future incomplete task to n=0.") + self.add_to_pool(itask) + # (The transient used for spawning outputs is now not transient.) + itask.transient = False if no_op: return False