diff --git a/CODEOWNERS b/CODEOWNERS
index 2c99f38f231027ac8657c42a2bdfa74ff49e6e0e..76f18ffd72e0acff683c916ac0fb11c83ca2793f 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -167,7 +167,7 @@
 /Hlt/Hlt2Conf/python/Hlt2Conf/lines/rd/builders/baryonic_builders.py @vlisovsk @msaur
 
 # QEE
-/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/ @wbarter @ncooke @jideng @rjhunter @olupton @yqiu @cvazquez @hyin @dzuliani
+/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/ @wbarter @ncooke @jideng @rjhunter @cvazquez @hyin @dzuliani @lugrazet
 # Selection framework testbed
 /Hlt/Hlt2Conf/python/Hlt2Conf/lines/generic.py @nnolte @vrenaudi
 /Hlt/Hlt2Conf/python/Hlt2Conf/lines/dplus_hhh_test.py @nnolte @vrenaudi
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/high_mass_dimuon_tracking_efficiency.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/high_mass_dimuon_tracking_efficiency.py
index b3b9c1346a95da6df1bbecc660472b411f180ea1..be2085c52736a515960c949742495b66bf27ed9b 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/high_mass_dimuon_tracking_efficiency.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/high_mass_dimuon_tracking_efficiency.py
@@ -23,6 +23,7 @@ from PyConf.Algorithms import MuonProbeToLongMatcher
 
 from Moore.config import register_line_builder
 from Moore.lines import Hlt2Line
+from Moore.streams_hlt2 import DETECTOR_RAW_BANK_TYPES
 
 from RecoConf.reconstruction_objects import upfront_reconstruction
 
@@ -88,16 +89,14 @@ def make_Z0Combiner(particles, probe_charge, get_cuts, line):
 
 
 @configurable
-def make_Tag_Filter(particles, probe_charge, get_cuts, line):
+def make_Tag_Filter(particles, probe_charge, get_cuts):
     code = F.require_all(
         (F.CHARGE < 0) if probe_charge == 1 else (F.CHARGE > 0),
         F.PT > get_cuts['min_TagPT'],
         F.ISMUON(),
     )
     return ParticleFilter(
-        particles,
-        F.FILTER(code),
-        name=f"ZToMuMu_TrackEff_TagTrack_{line}_{{hash}}")
+        particles, F.FILTER(code), name="ZToMuMu_TrackEff_TagTrack_{hash}")
 
 
 @configurable
@@ -119,7 +118,7 @@ def create_Tag_Line(name, line, prescale, persistreco, probe_charge, get_cuts,
                     particles):
     probe_muons = make_Probe_Filter(particles, probe_charge, get_cuts, line)
     tag_muons = make_Tag_Filter(make_ismuon_long_muon(), probe_charge,
-                                get_cuts, line)
+                                get_cuts)
     Z0 = make_Z0Combiner([tag_muons, probe_muons], probe_charge, get_cuts,
                          line)
     return Hlt2Line(
@@ -127,6 +126,7 @@ def create_Tag_Line(name, line, prescale, persistreco, probe_charge, get_cuts,
         algs=upfront_reconstruction() + [tag_muons, probe_muons, Z0],
         prescale=prescale,
         persistreco=persistreco,
+        raw_banks=DETECTOR_RAW_BANK_TYPES,
         monitoring_variables=("m", "pt", "eta", "n_candidates"))
 
 
@@ -135,7 +135,7 @@ def create_Match_Line(name, line, prescale, persistreco, probe_charge,
                       get_cuts, particles):
     probe_muons = make_Probe_Filter(particles, probe_charge, get_cuts, line)
     tag_muons = make_Tag_Filter(make_ismuon_long_muon(), probe_charge,
-                                get_cuts, line)
+                                get_cuts)
     long_track = make_LongFilter(
         make_ismuon_long_muon(),
         probe_charge,
@@ -176,10 +176,10 @@ for method, get_cuts, myparticles in zip(
                 persistreco=True,
                 probe_charge=charge,
                 get_cuts=get_cuts,
-                get_particles=myparticles):
-            return create_Tag_Line(name, method + '_' + probe, prescale,
-                                   persistreco, probe_charge, get_cuts,
-                                   get_particles())
+                get_particles=myparticles,
+                line=method + '_' + probe):
+            return create_Tag_Line(name, line, prescale, persistreco,
+                                   probe_charge, get_cuts, get_particles())
 
         @register_line_builder(all_lines)
         @configurable
@@ -189,7 +189,7 @@ for method, get_cuts, myparticles in zip(
                 persistreco=True,
                 probe_charge=charge,
                 get_cuts=get_cuts,
-                get_particles=myparticles):
-            return create_Match_Line(name, method + '_' + probe, prescale,
-                                     persistreco, probe_charge, get_cuts,
-                                     get_particles())
+                get_particles=myparticles,
+                line=method + '_' + probe):
+            return create_Match_Line(name, line, prescale, persistreco,
+                                     probe_charge, get_cuts, get_particles())
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
index c1c55e3c9a85c57c86c40d0a28a711ccd54a0fd6..bfe5d807795e2a9621a4cc384cfebcc83aaf5de9 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/qee_builders.py
@@ -20,11 +20,13 @@ from PyConf import configurable
 from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner
 from Hlt2Conf.standard_particles import make_ismuon_long_muon, make_long_muons
 from Hlt2Conf.standard_particles import make_long_electrons_with_brem, make_down_electrons_no_brem
+from Hlt2Conf.probe_muons import make_velomuon_muons, make_downstream_muons, make_muonut_muons
 from Hlt2Conf.standard_jets import make_pf_particles, build_jets, tag_jets
 from Hlt2Conf.lines.jets.topobits import make_topo_2body
 from Hlt2Conf.standard_particles import make_photons
 from Hlt2Conf.lines.qee.high_mass_dimuon import make_dimuon_novxt
 from Hlt2Conf.lines.qee.high_mass_dielec import make_dielec_novxt
+from Hlt2Conf.lines.qee.high_mass_dimuon_tracking_efficiency import VeloMuon_cuts, Downstream_cuts, UTMuon_cuts
 
 
 @configurable
@@ -176,3 +178,35 @@ def Z_To_lepts_filter(lepton_type="mu", min_pt=10. * GeV):
             min_mass=40. * GeV)
 
     return zcand
+
+
+def make_Z_trkeff_cand(trkeff_method=""):
+    """
+    Builds Z-like Tag&Probe Dimuon candidates. 
+    Use: Hlt2_ZTrkEff cuts to generate candidates for Spruce_ZTrkEff.
+    Requires `cc` in decay descriptor to ensure probe='mu+' and probe='mu-' samples are both reconstructed.
+    """
+    decay_descriptor = "[Z0 -> mu- mu+]cc"
+    name_prefix = "SpruceQEE_TrackEff_ZToMuMu"
+    name = f"{name_prefix}_{trkeff_method}_Builder"
+
+    probe, cuts = {
+        "Downstream": (make_downstream_muons(), Downstream_cuts),
+        "UTMuon": (make_muonut_muons(), UTMuon_cuts),
+        "VeloMuon": (make_velomuon_muons(), VeloMuon_cuts)
+    }[trkeff_method]
+
+    filtered_probe = ParticleFilter(
+        probe,
+        F.FILTER(F.PT > cuts['min_ProbePT']),
+        name=f"{name_prefix}_{trkeff_method}_ProbeFilter")
+    filtered_tag = muon_filter(min_pt=cuts['min_TagPT'], require_muID=True)
+    masscomb_cut = F.math.in_range(cuts['min_Z0mass'], F.MASS,
+                                   cuts['max_Z0mass'])
+
+    return ParticleCombiner(
+        name=name,
+        Inputs=[filtered_tag, filtered_probe],
+        CombinationCut=masscomb_cut,
+        CompositeCut=masscomb_cut,
+        DecayDescriptor=decay_descriptor)
diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/spruce_qee.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/spruce_qee.py
index 714a63fed25fc00101b7378d16fa375a7d4a74d3..a4c2ae5cd7a4d9ca70bd6ff86e258c922f0777dd 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/spruce_qee.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/qee/spruce_qee.py
@@ -33,6 +33,7 @@ from Hlt2Conf.lines.qee.wz_boson_rare_decays import make_WZRareDecay_HadronGamma
 from Hlt2Conf.lines.qee.qee_builders import muon_filter
 from Hlt2Conf.lines.qee.single_high_pt_muon import make_isolated_muons
 from Hlt2Conf.lines.qee.di_bjet import make_SVTagDijets_cand, make_Dijets_cand, make_Trijets_cand, make_TrijetsTwoSVTag_cand
+from Hlt2Conf.lines.qee.qee_builders import make_Z_trkeff_cand
 
 # Necessary imports to hlt2_filter robustly;
 from inspect import signature
@@ -40,8 +41,14 @@ from Hlt2Conf.lines.qee.high_mass_dimuon import z_to_mu_mu_line, z_to_mu_mu_sing
 from Hlt2Conf.lines.qee.high_mass_dielec import z_to_e_e_line, same_sign_dielec_line
 from Hlt2Conf.lines.qee.single_high_pt_muon import threshold_map as muon_thresholds
 from Hlt2Conf.lines.qee.single_high_pt_muon import single_muon_highpt_line, single_muon_highpt_prescale_line, single_muon_highpt_iso_line, single_muon_highpt_nomuid_line
+from Hlt2Conf.lines.qee.high_mass_dimuon_tracking_efficiency import all_lines as trkeff_lines
 
 sprucing_lines = {}
+sprucing_trkeff_lines = {}
+
+trkeff_tag_linenames = [
+    linename for linename in trkeff_lines.keys() if "Tag" in linename
+]
 
 
 def _hlt2_decision_name(line_defn):
@@ -160,6 +167,37 @@ def same_sign_dielec_sprucing_line(name='SpruceQEE_DiElectronSameSign',
         prescale=prescale)
 
 
+################ Z -> mumu trkeff lines ################
+# TODO register these lines in sprucing_lines dictionary for running over 2024 HLT2-processed data.
+# Not currently registered as the upstream HLT2 lines did not persist raw banks in 2023.
+# see: https://gitlab.cern.ch/lhcb/Moore/-/issues/661
+for trkeff_method in ["Downstream", "VeloMuon", "UTMuon"]:
+
+    @register_line_builder(sprucing_trkeff_lines)
+    @configurable
+    def z_to_mu_mu_trkeff_tag_sprucing_lines(
+            trkeff_method=trkeff_method,
+            name=f'SpruceQEE_ZToMuMu_TrackEff_{trkeff_method}_Tag',
+            prescale=1):
+        """
+        Z0 boson decay to two muons line, where one is a Tag and the other a Probe muon, for TrackEfficiency studies.
+        passthrough after Hlt2QEE_TrackEff_ZToMuMu_{trkeff_method}_{probe=mup,mum}_Tag
+        """
+        line_alg = make_Z_trkeff_cand(trkeff_method=trkeff_method)
+        hlt2_tag_lines_for_method = [
+            string for string in trkeff_tag_linenames
+            if trkeff_method in string
+        ]
+        hlt2_filters = [
+            f"{line_name}Decision" for line_name in hlt2_tag_lines_for_method
+        ]
+        return SpruceLine(
+            name=name,
+            algs=upfront_reconstruction() + [line_alg],
+            hlt2_filter_code=hlt2_filters,
+            prescale=prescale)
+
+
 ################ Z + Jet lines ################
 @register_line_builder(sprucing_lines)
 @configurable