diff --git a/tests/functional/cylc-set/00-set-succeeded.t b/tests/functional/cylc-set/00-set-succeeded.t
new file mode 100644
index 00000000000..009b5c16ff3
--- /dev/null
+++ b/tests/functional/cylc-set/00-set-succeeded.t
@@ -0,0 +1,59 @@
+#!/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 set" proposal examples.
+# Set incomplete failed tasks to succeeded.
+
+. "$(dirname "$0")/test_header"
+set_test_number 6
+
+install_and_validate
+reftest_run
+
+for TASK in foo bar
+do
+ sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT status FROM task_states WHERE name is \"$TASK\"" > "${TASK}.1"
+
+ cmp_ok ${TASK}.1 - << __OUT__
+succeeded
+__OUT__
+
+ sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT outputs FROM task_outputs WHERE name is \"$TASK\"" > "${TASK}.2"
+
+ # Json string list of outputs from the db may not be ordered correctly.
+ # E.g., '["submitted", "started", "succeeded", "failed"]'.
+ python3 - << __END__ > "${TASK}.3"
+import json
+with open("${TASK}.2", 'r') as f:
+ print(
+ ','.join(
+ sorted(
+ json.load(f)
+ )
+ )
+ )
+__END__
+
+ cmp_ok "${TASK}.3" - << __OUT__
+failed,started,submitted,succeeded
+__OUT__
+
+done
+purge
diff --git a/tests/functional/cylc-set/00-set-succeeded/flow.cylc b/tests/functional/cylc-set/00-set-succeeded/flow.cylc
new file mode 100644
index 00000000000..2385af8b427
--- /dev/null
+++ b/tests/functional/cylc-set/00-set-succeeded/flow.cylc
@@ -0,0 +1,41 @@
+# 1. foo and bar fail incomplete.
+# 2. setter sets foo and bar to succeeded.
+# 3. foo and bar are completed, post runs, scheduler shuts down.
+
+[scheduler]
+ [[events]]
+ inactivity timeout = PT30S
+ abort on inactivity timeout = True
+ expected task failures = 1/foo, 1/bar
+
+[task parameters]
+ m = 1..2
+
+[scheduling]
+ [[graph]]
+ R1 = """
+ foo & bar => post
+ setter
+ """
+[runtime]
+ [[post]]
+ [[foo, bar]]
+ script = false
+ [[setter]]
+ script = """
+ # wait for foo and bar to fail.
+ for TASK in foo bar
+ do
+ cylc workflow-state \
+ --max-polls=10 \
+ --interval=1 \
+ --task=$TASK \
+ --point=${CYLC_TASK_CYCLE_POINT} \
+ --status=failed \
+ $CYLC_WORKFLOW_ID
+ done
+ # set foo succeeded (via --output)
+ cylc set -o succeeded $CYLC_WORKFLOW_ID//$CYLC_TASK_CYCLE_POINT/foo
+ # set bar succeeded (via default)
+ cylc set $CYLC_WORKFLOW_ID//$CYLC_TASK_CYCLE_POINT/bar
+ """
diff --git a/tests/functional/cylc-set/00-set-succeeded/reference.log b/tests/functional/cylc-set/00-set-succeeded/reference.log
new file mode 100644
index 00000000000..26468845a5c
--- /dev/null
+++ b/tests/functional/cylc-set/00-set-succeeded/reference.log
@@ -0,0 +1,5 @@
+1/setter -triggered off [] in flow 1
+1/foo -triggered off [] in flow 1
+1/bar -triggered off [] in flow 1
+1/post_m1 -triggered off ['1/bar', '1/foo'] in flow 1
+1/post_m2 -triggered off ['1/bar', '1/foo'] in flow 1
diff --git a/tests/functional/cylc-set/01-off-flow-pre.t b/tests/functional/cylc-set/01-off-flow-pre.t
new file mode 100644
index 00000000000..56eb6d72dd0
--- /dev/null
+++ b/tests/functional/cylc-set/01-off-flow-pre.t
@@ -0,0 +1,37 @@
+#!/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 set" proposal examples.
+# Set off-flow prerequisites to prevent a new flow from stalling.
+
+. "$(dirname "$0")/test_header"
+set_test_number 8
+
+install_and_validate
+reftest_run
+
+grep_workflow_log_ok ab "1/a does not depend on 1/b_cold:succeeded"
+grep_workflow_log_ok ac "1/a does not depend on 1/c_cold:succeeded"
+
+grep_workflow_log_ok ba "1/b does not depend on 1/a_cold:succeeded"
+grep_workflow_log_ok bc "1/b does not depend on 1/c_cold:succeeded"
+
+grep_workflow_log_ok ca "1/c does not depend on 1/a_cold:succeeded"
+grep_workflow_log_ok cb "1/c does not depend on 1/b_cold:succeeded"
+
+purge
diff --git a/tests/functional/cylc-set/01-off-flow-pre/flow.cylc b/tests/functional/cylc-set/01-off-flow-pre/flow.cylc
new file mode 100644
index 00000000000..5c2ae5b97c4
--- /dev/null
+++ b/tests/functional/cylc-set/01-off-flow-pre/flow.cylc
@@ -0,0 +1,35 @@
+# start a new flow after setting off-flow prerequites to avoid stall.
+
+[scheduler]
+ [[events]]
+ stall timeout = PT0S
+ abort on stall timeout = True
+ inactivity timeout = PT30S
+ abort on inactivity timeout = True
+
+[scheduling]
+ [[graph]]
+ R1 = """
+ # the tasks we want the flow to run
+ a => b => c => reflow
+ # the off-flow prerequisites
+ a_cold => a
+ b_cold => b
+ c_cold => c
+ """
+[runtime]
+ [[a, b, c]]
+ [[a_cold, b_cold, c_cold]]
+ [[reflow]]
+ script = """
+ if (( CYLC_TASK_SUBMIT_NUMBER == 1 )); then
+ # set off-flow prerequisites (and trigger 1/a)
+ cylc set --flow=new \
+ --pre=1/a_cold:succeeded \
+ --pre=1/b_cold:succeeded \
+ --pre=1/c_cold:succeeded \
+ ${CYLC_WORKFLOW_ID}//1/a \
+ ${CYLC_WORKFLOW_ID}//1/b \
+ ${CYLC_WORKFLOW_ID}//1/c
+ fi
+ """
diff --git a/tests/functional/cylc-set/01-off-flow-pre/reference.log b/tests/functional/cylc-set/01-off-flow-pre/reference.log
new file mode 100644
index 00000000000..07c980ca981
--- /dev/null
+++ b/tests/functional/cylc-set/01-off-flow-pre/reference.log
@@ -0,0 +1,11 @@
+1/c_cold -triggered off [] in flow 1
+1/a_cold -triggered off [] in flow 1
+1/b_cold -triggered off [] in flow 1
+1/a -triggered off ['1/a_cold'] in flow 1
+1/b -triggered off ['1/a', '1/b_cold'] in flow 1
+1/c -triggered off ['1/b', '1/c_cold'] in flow 1
+1/reflow -triggered off ['1/c'] in flow 1
+1/a -triggered off ['1/a_cold'] in flow 2
+1/b -triggered off ['1/a', '1/b_cold'] in flow 2
+1/c -triggered off ['1/b', '1/c_cold'] in flow 2
+1/reflow -triggered off ['1/c'] in flow 2
diff --git a/tests/functional/cylc-set/02-off-flow-out.t b/tests/functional/cylc-set/02-off-flow-out.t
new file mode 100644
index 00000000000..61102e3df7f
--- /dev/null
+++ b/tests/functional/cylc-set/02-off-flow-out.t
@@ -0,0 +1,44 @@
+#!/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 set" proposal examples.
+# Set off-flow outputs to prevent a new flow from stalling.
+
+. "$(dirname "$0")/test_header"
+set_test_number 11
+
+install_and_validate
+reftest_run
+
+# Check that we set:
+# - all the required outputs of a_cold
+# - the requested and implied outputs of b_cold and c_cold
+
+grep_workflow_log_ok grep-a1 'implied output "submitted" of 1/a_cold'
+grep_workflow_log_ok grep-a2 'implied output "started" of 1/a_cold'
+grep_workflow_log_ok grep-a3 'completing output "succeeded" of 1/a_cold'
+
+grep_workflow_log_ok grep-b1 'implied output "submitted" of 1/b_cold'
+grep_workflow_log_ok grep-b2 'implied output "started" of 1/b_cold'
+grep_workflow_log_ok grep-b3 'completing output "succeeded" of 1/b_cold'
+
+grep_workflow_log_ok grep-c1 'implied output "submitted" of 1/c_cold'
+grep_workflow_log_ok grep-c2 'implied output "started" of 1/c_cold'
+grep_workflow_log_ok grep-c3 'completing output "succeeded" of 1/c_cold'
+
+purge
diff --git a/tests/functional/cylc-set/02-off-flow-out/flow.cylc b/tests/functional/cylc-set/02-off-flow-out/flow.cylc
new file mode 100644
index 00000000000..f8f2001f077
--- /dev/null
+++ b/tests/functional/cylc-set/02-off-flow-out/flow.cylc
@@ -0,0 +1,32 @@
+# start a new flow after setting off-flow outputs to avoid stall.
+
+[scheduler]
+ [[events]]
+ stall timeout = PT0S
+ abort on stall timeout = True
+ inactivity timeout = PT30S
+ abort on inactivity timeout = True
+
+[scheduling]
+ [[graph]]
+ R1 = """
+ # the tasks we want the flow to run
+ a => b => c => reflow
+ # the off-flow prerequisites
+ a_cold => a
+ b_cold => b
+ c_cold => c
+ """
+[runtime]
+ [[a, b, c]]
+ [[a_cold, b_cold, c_cold]]
+ [[reflow]]
+ script = """
+ if (( CYLC_TASK_SUBMIT_NUMBER == 1 )); then
+ # set off-flow outputs of x_cold
+ cylc set --flow=new \
+ ${CYLC_WORKFLOW_ID}//1/a_cold \
+ ${CYLC_WORKFLOW_ID}//1/b_cold \
+ ${CYLC_WORKFLOW_ID}//1/c_cold
+ fi
+ """
diff --git a/tests/functional/cylc-set/02-off-flow-out/reference.log b/tests/functional/cylc-set/02-off-flow-out/reference.log
new file mode 100644
index 00000000000..07c980ca981
--- /dev/null
+++ b/tests/functional/cylc-set/02-off-flow-out/reference.log
@@ -0,0 +1,11 @@
+1/c_cold -triggered off [] in flow 1
+1/a_cold -triggered off [] in flow 1
+1/b_cold -triggered off [] in flow 1
+1/a -triggered off ['1/a_cold'] in flow 1
+1/b -triggered off ['1/a', '1/b_cold'] in flow 1
+1/c -triggered off ['1/b', '1/c_cold'] in flow 1
+1/reflow -triggered off ['1/c'] in flow 1
+1/a -triggered off ['1/a_cold'] in flow 2
+1/b -triggered off ['1/a', '1/b_cold'] in flow 2
+1/c -triggered off ['1/b', '1/c_cold'] in flow 2
+1/reflow -triggered off ['1/c'] in flow 2
diff --git a/tests/functional/cylc-set/03-set-failed.t b/tests/functional/cylc-set/03-set-failed.t
new file mode 100644
index 00000000000..061e92870e1
--- /dev/null
+++ b/tests/functional/cylc-set/03-set-failed.t
@@ -0,0 +1,69 @@
+#!/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 set" proposal examples.
+# check that we can set a dead orphaned job to failed.
+
+. "$(dirname "$0")/test_header"
+set_test_number 6
+
+install_and_validate
+
+run_ok play-it cylc play --debug "${WORKFLOW_NAME}"
+
+poll_grep_workflow_log -E "1/foo.* \(internal\)submitted"
+
+cylc set -o failed "${WORKFLOW_NAME}//1/foo"
+
+poll_grep_workflow_log -E "1/foo.* \(internal\)failed"
+poll_grep_workflow_log -E "1/foo.* did not complete required outputs"
+
+cylc stop --now --now --interval=2 --max-polls=5 "${WORKFLOW_NAME}"
+
+# Check the log for:
+# - set completion message
+# - implied outputs reported as already completed
+
+# order of output completion is currently not fixed (using a set of outputs).
+grep_workflow_log_ok grep-1 'set: implied output "submitted" of 1/foo' # already completed'
+grep_workflow_log_ok grep-2 'set: implied output "started" of 1/foo' # already completed'
+grep_workflow_log_ok grep-3 'set: completing output "failed" of 1/foo'
+
+# Check the DB records all the outputs.
+
+sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT outputs FROM task_outputs WHERE name is \"foo\"" > db-foo.1
+
+# Json string list of outputs from the db may not be ordered correctly.
+python3 - << __END__ > db-foo.2
+import json
+with open("db-foo.1", 'r') as f:
+ print(
+ ','.join(
+ sorted(
+ json.load(f)
+ )
+ )
+ )
+__END__
+
+cmp_ok "db-foo.2" - << __OUT__
+failed,started,submitted
+__OUT__
+
+purge
diff --git a/tests/functional/cylc-set/03-set-failed/flow.cylc b/tests/functional/cylc-set/03-set-failed/flow.cylc
new file mode 100644
index 00000000000..9d7514ccb83
--- /dev/null
+++ b/tests/functional/cylc-set/03-set-failed/flow.cylc
@@ -0,0 +1,18 @@
+# A single task that dies silently, requiring set to failed
+
+[scheduler]
+ [[events]]
+ inactivity timeout = PT20S
+ abort on inactivity timeout = True
+
+[scheduling]
+ [[graph]]
+ R1 = "foo"
+
+[runtime]
+ [[foo]]
+ init-script = cylc__job__disable_fail_signals
+ script = """
+ cylc__job__wait_cylc_message_started
+ exit 1
+ """
diff --git a/tests/functional/cylc-set/04-switch.t b/tests/functional/cylc-set/04-switch.t
new file mode 100644
index 00000000000..6b54727492c
--- /dev/null
+++ b/tests/functional/cylc-set/04-switch.t
@@ -0,0 +1,65 @@
+#!/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 set" proposal examples.
+# check that we can direct future optional branching a certain way
+
+. "$(dirname "$0")/test_header"
+set_test_number 5
+
+install_and_validate
+reftest_run
+
+# The branch-point task foo should be recorded as succeeded.
+
+sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT status FROM task_states WHERE name is \"foo\"" > db-foo.2
+
+cmp_ok "db-foo.2" - << __OUT__
+succeeded
+__OUT__
+
+# the outputs of foo should be recorded as:
+# a, succeeded
+# and the implied outputs (of succeeded) as well:
+# submitted, started
+
+sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT outputs FROM task_outputs WHERE name is \"foo\"" > db-foo.1
+
+# Json string list of outputs from the db may not be ordered correctly.
+python3 - << __END__ > db-foo.2
+import json
+with open("db-foo.1", 'r') as f:
+ print(
+ ','.join(
+ sorted(
+ json.load(f)
+ )
+ )
+ )
+__END__
+
+cmp_ok "db-foo.2" - << __OUT__
+a,started,submitted,succeeded
+__OUT__
+
+# Check the flow-wait worked
+grep_workflow_log_ok check-wait "1/foo.*spawning after flow wait" -E
+
+purge
diff --git a/tests/functional/cylc-set/04-switch/flow.cylc b/tests/functional/cylc-set/04-switch/flow.cylc
new file mode 100644
index 00000000000..8a0ded59ce0
--- /dev/null
+++ b/tests/functional/cylc-set/04-switch/flow.cylc
@@ -0,0 +1,31 @@
+# Set outputs of future task to direct the flow at an optional branch point.
+
+[scheduler]
+ [[events]]
+ inactivity timeout = PT20S
+ abort on inactivity timeout = True
+ stall timeout = PT0S
+ abort on stall timeout = True
+
+[scheduling]
+ [[graph]]
+ R1 = """
+ switcher => foo
+ foo:a? => a
+ foo:b? => b
+ """
+[runtime]
+ [[switcher]]
+ script = """
+ cylc set --output=a,succeeded --wait ${CYLC_WORKFLOW_ID}//1/foo
+ # wait for command actioned, to avoid race condition
+ cylc__job__poll_grep_workflow_log "actioned"
+ """
+ [[foo]]
+ script = "cylc message b" # always go b-way if I run
+ [[[outputs]]]
+ a = a
+ b = b
+ [[a]]
+ [[b]]
+ script = false
diff --git a/tests/functional/cylc-set/04-switch/reference.log b/tests/functional/cylc-set/04-switch/reference.log
new file mode 100644
index 00000000000..e4fe80d6929
--- /dev/null
+++ b/tests/functional/cylc-set/04-switch/reference.log
@@ -0,0 +1,2 @@
+1/switcher -triggered off [] in flow 1
+1/a -triggered off ['1/foo'] in flow 1
diff --git a/tests/functional/cylc-set/05-expire.t b/tests/functional/cylc-set/05-expire.t
new file mode 100644
index 00000000000..f0e5b5869b9
--- /dev/null
+++ b/tests/functional/cylc-set/05-expire.t
@@ -0,0 +1,42 @@
+#!/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 set" proposal examples.
+# check that forced task expiry works
+
+. "$(dirname "$0")/test_header"
+set_test_number 4
+
+install_and_validate
+reftest_run
+
+sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT status FROM task_states WHERE name is \"bar\"" > db-bar.1
+
+cmp_ok "db-bar.1" - << __OUT__
+expired
+__OUT__
+
+sqlite3 ~/cylc-run/"${WORKFLOW_NAME}"/log/db \
+ "SELECT outputs FROM task_outputs WHERE name is \"bar\"" > db-bar.2
+
+cmp_ok "db-bar.2" - << __OUT__
+["expired"]
+__OUT__
+
+purge
diff --git a/tests/functional/cylc-set/05-expire/flow.cylc b/tests/functional/cylc-set/05-expire/flow.cylc
new file mode 100644
index 00000000000..57d94dbb99e
--- /dev/null
+++ b/tests/functional/cylc-set/05-expire/flow.cylc
@@ -0,0 +1,24 @@
+# Expire a future task, so it won't run.
+
+[scheduler]
+ [[events]]
+ inactivity timeout = PT20S
+ abort on inactivity timeout = True
+ stall timeout = PT0S
+ abort on stall timeout = True
+
+[scheduling]
+ [[graph]]
+ R1 = """
+ # bar and baz should not run if bar expires
+ expirer => foo => bar? => baz
+ bar:expired?
+ """
+[runtime]
+ [[expirer]]
+ script = """
+ cylc set --output=expired ${CYLC_WORKFLOW_ID}//1/bar
+ """
+ [[foo]]
+ [[bar, baz]]
+ script = false
diff --git a/tests/functional/cylc-set/05-expire/reference.log b/tests/functional/cylc-set/05-expire/reference.log
new file mode 100644
index 00000000000..0966b1b6f90
--- /dev/null
+++ b/tests/functional/cylc-set/05-expire/reference.log
@@ -0,0 +1,2 @@
+1/expirer -triggered off [] in flow 1
+1/foo -triggered off ['1/expirer'] in flow 1
diff --git a/tests/functional/cylc-set/06-parentless.t b/tests/functional/cylc-set/06-parentless.t
new file mode 100644
index 00000000000..7b05b43063b
--- /dev/null
+++ b/tests/functional/cylc-set/06-parentless.t
@@ -0,0 +1,30 @@
+#!/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 set" proposal examples.
+# Check spawning a parentless task without ignoring xtriggers.
+
+. "$(dirname "$0")/test_header"
+set_test_number 3
+
+install_and_validate
+REFTEST_OPTS="--start-task=1800/a" reftest_run
+
+grep_workflow_log_ok clock "xtrigger satisfied: wall_clock"
+
+purge
diff --git a/tests/functional/cylc-set/06-parentless/flow.cylc b/tests/functional/cylc-set/06-parentless/flow.cylc
new file mode 100644
index 00000000000..5078b84e484
--- /dev/null
+++ b/tests/functional/cylc-set/06-parentless/flow.cylc
@@ -0,0 +1,22 @@
+# Start this with --start-task=1800/a.
+# It should stall because x => b is off-flow.
+# The stall handler should unstall it by spawning x.
+# The log should show a clock-trigger check before x runs.
+
+[scheduler]
+ [[events]]
+ inactivity timeout = PT30S
+ abort on inactivity timeout = True
+ stall timeout = PT10S
+ abort on stall timeout = True
+ stall handlers = "cylc set --pre=all %(workflow)s//1800/x"
+
+[scheduling]
+ initial cycle point = 1800
+ [[graph]]
+ R1 = """
+ a => b
+ @wall_clock => x => b
+ """
+[runtime]
+ [[a, b, x]]
diff --git a/tests/functional/cylc-set/06-parentless/reference.log b/tests/functional/cylc-set/06-parentless/reference.log
new file mode 100644
index 00000000000..f977d1f086b
--- /dev/null
+++ b/tests/functional/cylc-set/06-parentless/reference.log
@@ -0,0 +1,4 @@
+Start task: ['1800/a']
+18000101T0000Z/a -triggered off [] in flow 1
+18000101T0000Z/x -triggered off [] in flow 1
+18000101T0000Z/b -triggered off ['18000101T0000Z/a', '18000101T0000Z/x'] in flow 1
diff --git a/tests/functional/cylc-set/test_header b/tests/functional/cylc-set/test_header
new file mode 120000
index 00000000000..90bd5a36f92
--- /dev/null
+++ b/tests/functional/cylc-set/test_header
@@ -0,0 +1 @@
+../lib/bash/test_header
\ No newline at end of file