diff --git a/MooreOnlineConf/options/ft.py b/MooreOnlineConf/options/ft.py
index 4e0f4e8a61e28adb29a755141a806b90bcf7f6db..dd756ca7d0d9e8370ebb356a018707f652814e00 100644
--- a/MooreOnlineConf/options/ft.py
+++ b/MooreOnlineConf/options/ft.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration           #
+# (c) Copyright 2000-2024 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -7,46 +7,94 @@
 # In applying this licence, CERN does not waive the privileges and immunities #
 # granted to it by virtue of its status as an Intergovernmental Organization  #
 # or submit itself to any jurisdiction.                                       #
-#############################################################################
+###############################################################################
+from PyConf.application import (
+    configure_input,
+    configure,
+    default_raw_banks,
+    make_odin,
+)
+from PyConf.Algorithms import (
+    FTRawBankDecoder,
+    FTLiteClusterMonitor,
+    FTLiteClusterTAEMonitor,
+)
+from MooreOnlineConf.utils import (
+    common_monitors_node,
+    passes_rb,
+    RoutingBit,
+    decode_tae,
+    if_then,
+    run_all,
+)
+from Moore import options
+import os
 
-from PyConf.application import default_raw_event, default_raw_banks, make_odin
-from Moore import options, run_reconstruction
-from PyConf.Algorithms import FTDigitMonitor, FTNZSRawBankDecoder
-from PyConf.Algorithms import FTClusterMonitor, FTRawBankDecoder
-from Moore.config import Reconstruction
-from RecoConf.standalone import reco_prefilters
+try:
+    import OnlineEnvBase as OnlineEnv
+    TAE_HALF_WINDOW = OnlineEnv.TAE
+except ImportError:
+    TAE_HALF_WINDOW = 3
 
-options.dddb_tag = 'upgrade/master'
-options.conddb_tag = 'upgrade/master'
+partition = os.environ.get("PARTITION", "LHCb")
+isLocalFlag = bool(partition == "LHCb")
 
 
-def ft_mon():
-    raw_event = default_raw_event(["FTNZS"])
-    raw_banks = default_raw_banks("FTGeneric")
+def main():
     odin = make_odin()
 
-    algs = []
-    if options.input_type.lower() == 'online':
-        from MooreOnlineConf.utils import update_and_reset
-        algs.append(update_and_reset())
+    def make_ft_clusters(name=""):
+        raw_banks = default_raw_banks("FTCluster")
+        ZS_decoder = FTRawBankDecoder(
+            name=f"FTRawBankDecoder{name}", Odin=odin, RawBanks=raw_banks)
+        return ZS_decoder.OutputLocation
+
+    # the standard monitor
+    zs_monitor_lumi = FTLiteClusterMonitor(
+        name="FTLiteClusterMonitorLumi",
+        allow_duplicate_instances_with_distinct_names=True,
+        InputODIN=odin,
+        ClusterLocation=make_ft_clusters())
+
+    zs_monitor_physics = FTLiteClusterMonitor(
+        name="FTLiteClusterMonitor",
+        allow_duplicate_instances_with_distinct_names=True,
+        InputODIN=odin,
+        ClusterLocation=make_ft_clusters())
 
-    ZS_decoder = FTRawBankDecoder(RawBanks=raw_banks)
-    ZS_monitor = FTClusterMonitor(
-        InputODIN=odin, ClusterLocation=ZS_decoder.OutputLocation)
-    algs += [
-        ZS_decoder,
-        ZS_monitor,
-    ]
+    # the TAE monitor
+    is_tae, tae_decoding, tae_odins, tae_data = decode_tae(
+        make_ft_clusters, TAE_HALF_WINDOW)
+    tae_monitor = FTLiteClusterTAEMonitor(
+        name="FTLiteClusterTAEMonitor",
+        ODINVector=list(tae_odins.values()),
+        InputVector=list(tae_data.values()),
+        SuperTAEHalfWindow=TAE_HALF_WINDOW)
 
-    NZS_decoder = FTNZSRawBankDecoder(RawEventLocations=raw_event)
-    NZS_monitor = FTDigitMonitor(
-        InputODIN=odin, DigitLocation=NZS_decoder.OutputLocation)
-    algs += [
-        NZS_decoder,
-        NZS_monitor,
-    ]
+    # assemble the control flow
+    if isLocalFlag:
+        top_node = run_all(
+            "top",
+            [
+                common_monitors_node(),  # common monitoring to all tasks
+                if_then("IfPHYSICS", passes_rb(RoutingBit.PHYSICS),
+                        zs_monitor_physics),
+                if_then("IfLUMI", passes_rb(RoutingBit.LUMI), zs_monitor_lumi),
+                if_then("IfTAE", is_tae,
+                        run_all("TAE", [tae_decoding, tae_monitor])),
+            ])
+    else:
+        top_node = run_all(
+            "top",
+            [
+                common_monitors_node(),  # common monitoring to all tasks
+                zs_monitor_physics,
+                if_then("IfTAE", is_tae,
+                        run_all("TAE", [tae_decoding, tae_monitor])),
+            ])
 
-    return Reconstruction('ft_mon', algs, reco_prefilters(gec=False))
+    return top_node
 
 
-run_reconstruction(options, ft_mon)
+configure_input(options)
+configure(options, main())