diff --git a/core-telemetry.cabal b/core-telemetry.cabal
--- a/core-telemetry.cabal
+++ b/core-telemetry.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           core-telemetry
-version:        0.2.0.1
+version:        0.2.2.0
 synopsis:       Advanced telemetry
 description:    This is part of a library to help build command-line programs, both tools and
                 longer-running daemons.
@@ -54,7 +54,7 @@
     , bytestring
     , chronologique
     , core-data >=0.3.2.2
-    , core-program >=0.4.5.3
+    , core-program >=0.4.6.1
     , core-text >=0.3.6.0
     , exceptions
     , http-streams
diff --git a/lib/Core/Telemetry.hs b/lib/Core/Telemetry.hs
--- a/lib/Core/Telemetry.hs
+++ b/lib/Core/Telemetry.hs
@@ -33,7 +33,7 @@
     -- * Internals
 
     -- |
-    -- Various elper functions.
+    -- Various helper functions.
     module Core.Telemetry.Identifiers
 ) where
 
diff --git a/lib/Core/Telemetry/Identifiers.hs b/lib/Core/Telemetry/Identifiers.hs
--- a/lib/Core/Telemetry/Identifiers.hs
+++ b/lib/Core/Telemetry/Identifiers.hs
@@ -18,6 +18,7 @@
     -- * Traces and Spans
     getIdentifierTrace,
     getIdentifierSpan,
+    setIdentifierSpan,
 
     -- * Internals
     createIdentifierTrace,
@@ -32,8 +33,9 @@
     toHexReversed32,
 ) where
 
-import Control.Concurrent.MVar (readMVar)
+import Control.Concurrent.MVar (modifyMVar_, readMVar)
 import Core.Program.Context
+import Core.Program.Logging
 import Core.System (unsafePerformIO)
 import Core.System.Base (liftIO)
 import Core.System.External (TimeStamp (unTimeStamp))
@@ -291,3 +293,27 @@
         datum <- readMVar v
 
         pure (spanIdentifierFrom datum)
+
+{- |
+Override the identifier of the current span, if you are currently within a
+span created by 'Core.Telemetry.Observability.encloseSpan'. This is an unsafe
+action, specifically and only for the situation where you need create a parent
+span for an asynchronous process whose unique identifier has already been
+nominated. In this scenario all child spans would already have been created
+with this span identifier as their parent, leaving you with the final task of
+creating a "root" span within the trace with that parent identifier.
+
+@since 0.2.1
+-}
+setIdentifierSpan :: Span -> Program t ()
+setIdentifierSpan unique = do
+    context <- getContext
+
+    internal ("span = " <> unSpan unique)
+
+    liftIO $ do
+        -- get the map out
+        let v = currentDatumFrom context
+        modifyMVar_
+            v
+            (\datum -> pure datum{spanIdentifierFrom = Just unique})
diff --git a/lib/Core/Telemetry/Observability.hs b/lib/Core/Telemetry/Observability.hs
--- a/lib/Core/Telemetry/Observability.hs
+++ b/lib/Core/Telemetry/Observability.hs
@@ -144,6 +144,7 @@
     Span (..),
     beginTrace,
     usingTrace,
+    usingTrace',
     setServiceName,
 
     -- * Spans
@@ -452,6 +453,16 @@
             Right value -> pure value
 
 {- |
+Send a span value up by hand.
+
+This handles a number of convenient things for you, and takes care of a few edge
+cases.
+
+
+@since 0.2.1
+-}
+
+{- |
 Start a new trace. A random identifier will be generated.
 
 You /must/ have a single \"root span\" immediately below starting a new trace.
@@ -511,6 +522,51 @@
 
     encloseTrace trace (Just parent) action
 
+{- |
+Create a new trace with the specified 'Trace' identifier. Unlike 'usingTrace'
+this does /not/ set the parent 'Span' identifier, thereby marking this as a
+new trace and causing the first span enclosed within this trace to be
+considered the \"root\" span of the trace. This is unusual and should only
+expected to be used in concert with the 'setIdentifierSpan' override to create
+a root spans in asynchronous processes /after/ all the child spans have
+already been composed and sent.
+
+Most times, you don't need this. You're much better off using 'beginTrace' to
+create a root span. However, life is not kind, and sometimes bad things happen
+to good abstractions. Maybe you're tracing your build system, which isn't
+obliging enough to be all contained in one Haskell process, but is a
+half-dozen steps shotgunned across several different processes. In situations
+like this, it's useful to be able to generate a 'Trace' identifier and 'Span'
+identifier, use that as the parent across several different process
+executions, hanging children spans off of this as you go, then manually send
+up the root span at the end of it all.
+
+@
+    trace <- ...
+    unique <- ...
+
+    -- many child spans in other processes have used these as trace
+    -- identifiers and parent span identifier. Now form the root span thereby
+    -- finishing the trace.
+
+    'usingTrace'' trace $ do
+        'encloseSpan' \"Launch Missiles\" $ do
+            'setStartTime' start
+            'setIdentifierSpan' unique
+            'telemetry'
+                [ 'metric' ...
+                ]
+@
+
+@since 0.2.1
+-}
+usingTrace' :: Trace -> Program τ α -> Program τ α
+usingTrace' trace action = do
+    internal "Using trace"
+    internal ("trace = " <> unTrace trace)
+
+    encloseTrace trace Nothing action
+
 encloseTrace :: Trace -> Maybe Span -> Program τ α -> Program τ α
 encloseTrace trace possibleParent action = do
     context <- getContext
@@ -578,7 +634,10 @@
             )
   where
     f :: Map JsonKey JsonValue -> MetricValue -> Map JsonKey JsonValue
-    f acc (MetricValue k v) = insertKeyValue k v acc
+    f acc (MetricValue k@(JsonKey text) v) =
+        if nullRope text
+            then error "Empty metric field name not allowed"
+            else insertKeyValue k v acc
 
 {- |
 Record telemetry about an event. Specify a label for the event and then
@@ -629,7 +688,10 @@
             writeTQueue tel (Just datum')
   where
     f :: Map JsonKey JsonValue -> MetricValue -> Map JsonKey JsonValue
-    f acc (MetricValue k v) = insertKeyValue k v acc
+    f acc (MetricValue k@(JsonKey text) v) =
+        if nullRope text
+            then error "Empty metric field name not allowed"
+            else insertKeyValue k v acc
 
 -- get current time after digging out datum and override spanTimeFrom before
 -- sending Datum
