diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,18 @@
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.9.12] - 2022-06-28
+
+### Added
+
+ - Nix 2.16 support
+
+ - Nix 2.15 support
+
+### Fixed
+
+ - Do not `chdir` the build worker. This functionality of the `process` package appears unreliable, but is not needed.
+
 ## [0.9.11] - 2022-03-06
 
 ### BREAKING
diff --git a/cbits/hercules-logger.cxx b/cbits/hercules-logger.cxx
--- a/cbits/hercules-logger.cxx
+++ b/cbits/hercules-logger.cxx
@@ -12,6 +12,16 @@
   return millis;
 }
 
+#if NIX_IS_AT_LEAST(2, 15, 0)
+void HerculesLogger::log(nix::Verbosity lvl, std::string_view s) {
+  push(std::make_unique<LogEntry>(LogEntry {
+    .entryType = 1,
+    .level = lvl,
+    .ms = getMs(),
+    .text = std::string(s)
+  }));
+}
+#else
 void HerculesLogger::log(nix::Verbosity lvl, const nix::FormatOrString & fs) {
   push(std::make_unique<LogEntry>(LogEntry {
     .entryType = 1,
@@ -20,6 +30,9 @@
     .text = fs.s
   }));
 }
+#endif
+
+
 
 // TODO structured
 void HerculesLogger::logEI(const nix::ErrorInfo & ei) {
diff --git a/cbits/hercules-logger.hh b/cbits/hercules-logger.hh
--- a/cbits/hercules-logger.hh
+++ b/cbits/hercules-logger.hh
@@ -41,7 +41,11 @@
     Fields fields;
   };
 
+#if NIX_IS_AT_LEAST(2, 15, 0)
+  void log(nix::Verbosity lvl, const std::string_view s) override;
+#else
   void log(nix::Verbosity lvl, const nix::FormatOrString & fs) override;
+#endif
   void startActivity(nix::ActivityId act, nix::Verbosity lvl, nix::ActivityType type,
       const std::string & s, const Fields & fields, nix::ActivityId parent) override;
   void stopActivity(nix::ActivityId act) override;
diff --git a/cbits/nix-2.4/hercules-store.cxx b/cbits/nix-2.4/hercules-store.cxx
--- a/cbits/nix-2.4/hercules-store.cxx
+++ b/cbits/nix-2.4/hercules-store.cxx
@@ -245,6 +245,12 @@
 }
 #endif
 
+#if NIX_IS_AT_LEAST(2,15,0)
+std::optional<TrustedFlag> WrappingStore::isTrustedClient() {
+  return wrappedStore->isTrustedClient();
+}
+#endif
+
 /////
 
 HerculesStore::HerculesStore(const Params& params, ref<Store> storeToWrap)
diff --git a/cbits/nix-2.4/hercules-store.hh b/cbits/nix-2.4/hercules-store.hh
--- a/cbits/nix-2.4/hercules-store.hh
+++ b/cbits/nix-2.4/hercules-store.hh
@@ -158,6 +158,10 @@
   virtual void createUser(const std::string & userName, uid_t userId) override;
 #endif
 
+#if NIX_IS_AT_LEAST(2,15,0)
+  virtual std::optional<TrustedFlag> isTrustedClient() override;
+#endif
+
 };
 
 class HerculesStore final : public WrappingStore {
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker.hs
@@ -11,10 +11,10 @@
 
 import Conduit
 import Control.Concurrent.STM hiding (check)
-import qualified Control.Exception.Lifted as EL
+import Control.Exception.Lifted qualified as EL
 import Control.Monad.Except
 import Control.Monad.IO.Unlift
-import qualified Data.Conduit
+import Data.Conduit qualified
 import Data.Conduit.Extras (sinkChan, sinkChanTerminate, sourceChan)
 import Data.Conduit.Katip.Orphans ()
 import Data.Conduit.Serialization.Binary
@@ -22,19 +22,19 @@
     conduitEncode,
   )
 import Data.IORef
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Data.Vector (Vector)
-import qualified Data.Vector as V
-import qualified Hercules.API.Agent.LifeCycle.ServiceInfo
+import Data.Vector qualified as V
+import Hercules.API.Agent.LifeCycle.ServiceInfo qualified
 import Hercules.API.Logs.LogEntry (LogEntry)
-import qualified Hercules.API.Logs.LogEntry as LogEntry
+import Hercules.API.Logs.LogEntry qualified as LogEntry
 import Hercules.API.Logs.LogHello (LogHello (LogHello, clientProtocolVersion, storeProtocolVersion))
 import Hercules.API.Logs.LogMessage (LogMessage)
-import qualified Hercules.API.Logs.LogMessage as LogMessage
+import Hercules.API.Logs.LogMessage qualified as LogMessage
 import Hercules.Agent.Sensitive
-import qualified Hercules.Agent.Socket as Socket
+import Hercules.Agent.Socket qualified as Socket
 import Hercules.Agent.Worker.Build (runBuild)
-import qualified Hercules.Agent.Worker.Build.Logger as Logger
+import Hercules.Agent.Worker.Build.Logger qualified as Logger
 import Hercules.Agent.Worker.Conduit (takeCWhileStopEarly, withMessageLimit)
 import Hercules.Agent.Worker.Effect (runEffect)
 import Hercules.Agent.Worker.Env (HerculesState (..))
@@ -45,34 +45,34 @@
 import Hercules.Agent.WorkerProtocol.Command
   ( Command,
   )
-import qualified Hercules.Agent.WorkerProtocol.Command as Command
-import qualified Hercules.Agent.WorkerProtocol.Command.Build as Build
-import qualified Hercules.Agent.WorkerProtocol.Command.BuildResult as BuildResult
-import qualified Hercules.Agent.WorkerProtocol.Command.Effect as Effect
+import Hercules.Agent.WorkerProtocol.Command qualified as Command
+import Hercules.Agent.WorkerProtocol.Command.Build qualified as Build
+import Hercules.Agent.WorkerProtocol.Command.BuildResult qualified as BuildResult
+import Hercules.Agent.WorkerProtocol.Command.Effect qualified as Effect
 import Hercules.Agent.WorkerProtocol.Command.Eval
   ( Eval,
   )
-import qualified Hercules.Agent.WorkerProtocol.Command.Eval as Eval
+import Hercules.Agent.WorkerProtocol.Command.Eval qualified as Eval
 import Hercules.Agent.WorkerProtocol.Event
   ( Event (Exception),
   )
-import qualified Hercules.Agent.WorkerProtocol.Event as Event
-import qualified Hercules.Agent.WorkerProtocol.LogSettings as LogSettings
+import Hercules.Agent.WorkerProtocol.Event qualified as Event
+import Hercules.Agent.WorkerProtocol.LogSettings qualified as LogSettings
 import Hercules.CNix as CNix
 import Hercules.CNix.Expr (init, setExtraStackOverflowHandlerToSleep)
 import Hercules.CNix.Util (installDefaultSigINTHandler)
 import Hercules.CNix.Verbosity (setShowTrace)
 import Hercules.Error
 import Katip
-import qualified Network.URI
+import Network.URI qualified
 import Protolude hiding (bracket, catch, check, evalState, wait, withAsync, yield)
-import qualified System.Environment as Environment
+import System.Environment qualified as Environment
 import System.IO (BufferMode (LineBuffering), hSetBuffering)
 import System.Posix.Signals (Handler (Catch), installHandler, raiseSignal, sigINT, sigTERM)
 import System.Timeout (timeout)
 import UnliftIO.Async (wait, withAsync)
 import Prelude ()
-import qualified Prelude
+import Prelude qualified
 
 main :: IO ()
 main = do
@@ -258,7 +258,7 @@
     safeSchemes = "ssh:// https://"
     allSchemes = safeSchemes <> " http:// git://"
 
-logger :: (MonadIO m, MonadUnliftIO m, KatipContext m) => LogSettings.LogSettings -> Int -> ConduitM () (Vector LogEntry) m () -> m ()
+logger :: (MonadUnliftIO m, KatipContext m) => LogSettings.LogSettings -> Int -> ConduitM () (Vector LogEntry) m () -> m ()
 logger logSettings_ storeProtocolVersionValue entriesSource = do
   socketConfig <- liftIO $ makeSocketConfig logSettings_ storeProtocolVersionValue
   let withPings socket m =
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build.hs
@@ -6,21 +6,21 @@
 import Conduit
 import Data.Conduit.Katip.Orphans ()
 import Hercules.Agent.Worker.Build.Prefetched (buildDerivation)
-import qualified Hercules.Agent.Worker.Build.Prefetched as Build
-import qualified Hercules.Agent.WorkerProtocol.Command.Build as Command.Build
+import Hercules.Agent.Worker.Build.Prefetched qualified as Build
+import Hercules.Agent.WorkerProtocol.Command.Build qualified as Command.Build
 import Hercules.Agent.WorkerProtocol.Event (Event)
-import qualified Hercules.Agent.WorkerProtocol.Event as Event
-import qualified Hercules.Agent.WorkerProtocol.Event.BuildResult as Event.BuildResult
+import Hercules.Agent.WorkerProtocol.Event qualified as Event
+import Hercules.Agent.WorkerProtocol.Event.BuildResult qualified as Event.BuildResult
 import Hercules.CNix
   ( DerivationOutput (derivationOutputName, derivationOutputPath),
     getDerivationOutputs,
   )
-import qualified Hercules.CNix as CNix
+import Hercules.CNix qualified as CNix
 import Hercules.CNix.Store (Store, queryPathInfo, validPathInfoNarHash32, validPathInfoNarSize)
 import Katip
 import Protolude hiding (yield)
 
-runBuild :: (MonadIO m, KatipContext m) => Store -> Command.Build.Build -> ConduitT i Event m ()
+runBuild :: (KatipContext m) => Store -> Command.Build.Build -> ConduitT i Event m ()
 runBuild store build = do
   let extraPaths = Command.Build.inputDerivationOutputPaths build
       drvPath = encodeUtf8 $ Command.Build.drvPath build
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger.hs
@@ -6,19 +6,19 @@
 module Hercules.Agent.Worker.Build.Logger (initLogger, withLoggerConduit, tapper, withTappedStderr, batch, unbatch, filterProgress, nubProgress) where
 
 import Conduit (MonadUnliftIO, filterC)
-import qualified Data.ByteString.Char8 as BSC
+import Data.ByteString.Char8 qualified as BSC
 import Data.ByteString.Unsafe (unsafePackMallocCString)
 import Data.Conduit (ConduitT, Flush (..), await, awaitForever, yield)
 import Data.Vector (Vector)
-import qualified Data.Vector as V
+import Data.Vector qualified as V
 import Foreign (alloca, nullPtr, peek)
 import Hercules.API.Logs.LogEntry (LogEntry)
-import qualified Hercules.API.Logs.LogEntry as LogEntry
+import Hercules.API.Logs.LogEntry qualified as LogEntry
 import Hercules.Agent.Worker.Build.Logger.Context (Fields, HerculesLoggerEntry, context)
 import Hercules.CNix.Store.Context (unsafeMallocBS)
 import Katip
-import qualified Language.C.Inline.Cpp as C
-import qualified Language.C.Inline.Cpp.Exception as C
+import Language.C.Inline.Cpp qualified as C
+import Language.C.Inline.Cpp.Exception qualified as C
 import Protolude hiding (bracket, finally, mask_, onException, tryJust, wait, withAsync, yield)
 import System.IO (BufferMode (LineBuffering), hSetBuffering)
 import System.IO.Error (isEOFError)
@@ -60,25 +60,25 @@
         (\buf -> [C.block| void { delete $(LogEntryQueue *buf); }|])
         ( \buf -> do
             [C.block| void {
-        herculesLogger->popMany($(int limit), *$(LogEntryQueue *buf));
-        }|]
+              herculesLogger->popMany($(int limit), *$(LogEntryQueue *buf));
+            }|]
             let getBufHeadAndReinsertClose =
                   [C.block| HerculesLoggerEntry * {
-              LogEntryQueue &buf = *$(LogEntryQueue *buf);
-              if (buf.empty()) {
-                return nullptr;
-              } else {
-                auto r = buf.front().get();
-                if (r == nullptr) {
-                  herculesLogger->close();
-                }
-                return r;
-              }
-            }|]
+                    LogEntryQueue &buf = *$(LogEntryQueue *buf);
+                    if (buf.empty()) {
+                      return nullptr;
+                    } else {
+                      auto r = buf.front().get();
+                      if (r == nullptr) {
+                        herculesLogger->close();
+                      }
+                      return r;
+                    }
+                  }|]
                 dropBufHead =
                   [C.block| void { 
-            $(LogEntryQueue *buf)->pop();
-          }|]
+                    $(LogEntryQueue *buf)->pop();
+                  }|]
                 popBufHead = do
                   hdN <- getBufHeadAndReinsertClose
                   forNonNull hdN $ \hd -> do
@@ -248,7 +248,7 @@
 -- Conduits for logger
 --
 
-withLoggerConduit :: (MonadIO m, MonadUnliftIO m) => (ConduitT () (Vector LogEntry) m () -> m ()) -> m a -> m a
+withLoggerConduit :: (MonadUnliftIO m) => (ConduitT () (Vector LogEntry) m () -> m ()) -> m a -> m a
 withLoggerConduit logger io = withAsync (logger popper) $ \popperAsync ->
   ((io `finally` liftIO close) <* wait popperAsync) `onException` liftIO (timeout 2_000_000 (wait popperAsync))
   where
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger/Context.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger/Context.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger/Context.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Logger/Context.hs
@@ -10,10 +10,10 @@
   )
 where
 
-import qualified Data.Map as M
-import qualified Language.C.Inline.Context as C
-import qualified Language.C.Inline.Cpp as C
-import qualified Language.C.Types as C
+import Data.Map qualified as M
+import Language.C.Inline.Context qualified as C
+import Language.C.Inline.Cpp qualified as C
+import Language.C.Types qualified as C
 import Protolude
 
 data HerculesLoggerEntry
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs
@@ -18,13 +18,13 @@
   )
 where
 
-import qualified Data.ByteString.Char8 as C8
+import Data.ByteString.Char8 qualified as C8
 import Foreign (alloca, peek)
 import Foreign.C (peekCString)
 import Hercules.CNix.Encapsulation
 import Hercules.CNix.Store
-import qualified Language.C.Inline.Cpp as C
-import qualified Language.C.Inline.Cpp.Exception as C
+import Language.C.Inline.Cpp qualified as C
+import Language.C.Inline.Cpp.Exception qualified as C
 import Protolude
 
 C.context context
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Conduit.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Conduit.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Conduit.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Conduit.hs
@@ -4,7 +4,7 @@
 
 import Data.Conduit (ConduitT, await, awaitForever, yield, (.|))
 import Data.IORef (IORef, modifyIORef, newIORef, readIORef)
-import qualified Data.Sequence as Seq
+import Data.Sequence qualified as Seq
 import Protolude hiding (pred, yield)
 
 tailC :: Monad m => Int -> ConduitT i i m ()
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Effect.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Effect.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Effect.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Effect.hs
@@ -5,19 +5,19 @@
 
 import Control.Monad.Catch (MonadThrow)
 import Hercules.Agent.Worker.Build.Prefetched (buildDerivation)
-import qualified Hercules.Agent.Worker.Build.Prefetched as Build
-import qualified Hercules.Agent.WorkerProtocol.Command.Effect as Command.Effect
+import Hercules.Agent.Worker.Build.Prefetched qualified as Build
+import Hercules.Agent.WorkerProtocol.Command.Effect qualified as Command.Effect
 import Hercules.Agent.WorkerProtocol.ViaJSON (fromViaJSON)
 import Hercules.CNix (Store)
-import qualified Hercules.CNix as CNix
+import Hercules.CNix qualified as CNix
 import Hercules.CNix.Store (Derivation)
 import Hercules.Effect (RunEffectParams (..))
-import qualified Hercules.Effect as Effect
+import Hercules.Effect qualified as Effect
 import Katip (KatipContext)
 import Protolude
 import UnliftIO.Directory (getCurrentDirectory)
 
-runEffect :: (MonadIO m, KatipContext m, MonadThrow m) => [(Text, Text)] -> Store -> Command.Effect.Effect -> m ExitCode
+runEffect :: (KatipContext m, MonadThrow m) => [(Text, Text)] -> Store -> Command.Effect.Effect -> m ExitCode
 runEffect extraNixOptions store command = do
   derivation <- prepareDerivation store command
   dir <- getCurrentDirectory
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Env.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Env.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Env.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Env.hs
@@ -4,7 +4,7 @@
 import Data.IORef (IORef)
 import Data.UUID (UUID)
 import Hercules.Agent.Worker.HerculesStore (HerculesStore)
-import qualified Hercules.Agent.WorkerProtocol.Command.BuildResult as BuildResult
+import Hercules.Agent.WorkerProtocol.Command.BuildResult qualified as BuildResult
 import Hercules.Agent.WorkerProtocol.Event (Event)
 import Hercules.CNix (Ref)
 import Hercules.CNix.Store (Store, StorePath)
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Error.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Error.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Error.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Error.hs
@@ -8,9 +8,9 @@
 import Foreign (alloca, peek)
 import Hercules.CNix.Encapsulation (HasEncapsulation (moveToForeignPtrWrapper))
 import Hercules.CNix.Store (StorePath (StorePath), traverseNonNull)
-import qualified Hercules.CNix.Store.Context
-import qualified Language.C.Inline.Cpp as C
-import qualified Language.C.Inline.Cpp.Exception as C
+import Hercules.CNix.Store.Context qualified
+import Language.C.Inline.Cpp qualified as C
+import Language.C.Inline.Cpp.Exception qualified as C
 import Protolude
 
 C.context (C.cppCtx <> C.fptrCtx <> C.bsCtx <> Hercules.CNix.Store.Context.context)
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/Evaluate.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/Evaluate.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/Evaluate.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/Evaluate.hs
@@ -15,56 +15,56 @@
 import Control.Monad.Except
 import Control.Monad.IO.Unlift
 import Data.Coerce (coerce)
-import qualified Data.Conduit
+import Data.Conduit qualified
 import Data.Conduit.Katip.Orphans ()
 import Data.IORef
-import qualified Data.Map as M
-import qualified Data.Set as S
-import qualified Data.Text as T
+import Data.Map qualified as M
+import Data.Set qualified as S
+import Data.Text qualified as T
 import Hercules.API.Agent.Evaluate.EvaluateEvent.OnPushHandlerEvent (OnPushHandlerEvent (OnPushHandlerEvent))
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.OnPushHandlerEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.OnPushHandlerEvent qualified
 import Hercules.API.Agent.Evaluate.EvaluateEvent.OnScheduleHandlerEvent (OnScheduleHandlerEvent (OnScheduleHandlerEvent), TimeConstraints (TimeConstraints))
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.OnScheduleHandlerEvent
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask as EvaluateTask
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask.OnPush as OnPush
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask.OnSchedule as OnSchedule
-import qualified Hercules.API.Agent.Evaluate.ImmutableGitInput as API.ImmutableGitInput
-import qualified Hercules.API.Agent.Evaluate.ImmutableInput as API.ImmutableInput
+import Hercules.API.Agent.Evaluate.EvaluateEvent.OnScheduleHandlerEvent qualified
+import Hercules.API.Agent.Evaluate.EvaluateTask qualified as EvaluateTask
+import Hercules.API.Agent.Evaluate.EvaluateTask.OnPush qualified as OnPush
+import Hercules.API.Agent.Evaluate.EvaluateTask.OnSchedule qualified as OnSchedule
+import Hercules.API.Agent.Evaluate.ImmutableGitInput qualified as API.ImmutableGitInput
+import Hercules.API.Agent.Evaluate.ImmutableInput qualified as API.ImmutableInput
 import Hercules.API.DayOfWeek (DayOfWeek (..))
 import Hercules.Agent.NixFile (HerculesCISchema, InputsSchema, OutputsSchema, getHerculesCI, homeExprRawValue, loadNixFile, parseExtraInputs)
-import qualified Hercules.Agent.NixFile as NixFile
+import Hercules.Agent.NixFile qualified as NixFile
 import Hercules.Agent.NixFile.HerculesCIArgs (CISystems (CISystems), HerculesCIMeta (HerculesCIMeta), fromGitSource)
-import qualified Hercules.Agent.NixFile.HerculesCIArgs
+import Hercules.Agent.NixFile.HerculesCIArgs qualified
 import Hercules.Agent.Worker.Env (HerculesState (..))
 import Hercules.Agent.Worker.Error (ExceptionText (exceptionTextDerivationPath), exceptionTextMessage, exceptionTextTrace, renderException, throwBuildError)
 import Hercules.Agent.Worker.HerculesStore (nixStore, setBuilderCallback)
 import Hercules.Agent.Worker.STM (asyncInTVarMap)
-import qualified Hercules.Agent.WorkerProtocol.Command.BuildResult as BuildResult
+import Hercules.Agent.WorkerProtocol.Command.BuildResult qualified as BuildResult
 import Hercules.Agent.WorkerProtocol.Command.Eval
   ( Eval,
   )
-import qualified Hercules.Agent.WorkerProtocol.Command.Eval as Eval
+import Hercules.Agent.WorkerProtocol.Command.Eval qualified as Eval
 import Hercules.Agent.WorkerProtocol.Event (Event)
-import qualified Hercules.Agent.WorkerProtocol.Event as Event
-import qualified Hercules.Agent.WorkerProtocol.Event.Attribute as Attribute
-import qualified Hercules.Agent.WorkerProtocol.Event.AttributeError as AttributeError
-import qualified Hercules.Agent.WorkerProtocol.Event.AttributeIFD as Event.AttributeIFD
-import qualified Hercules.Agent.WorkerProtocol.ViaJSON as ViaJSON
+import Hercules.Agent.WorkerProtocol.Event qualified as Event
+import Hercules.Agent.WorkerProtocol.Event.Attribute qualified as Attribute
+import Hercules.Agent.WorkerProtocol.Event.AttributeError qualified as AttributeError
+import Hercules.Agent.WorkerProtocol.Event.AttributeIFD qualified as Event.AttributeIFD
+import Hercules.Agent.WorkerProtocol.ViaJSON qualified as ViaJSON
 import Hercules.CNix as CNix
 import Hercules.CNix.Expr (Match (IsAttrs, IsString), NixAttrs, RawValue, addAllowedPath, addInternalAllowedPaths, autoCallFunction, evalArgs, getAttrBool, getAttrList, getAttrs, getDrvFile, getFlakeFromArchiveUrl, getFlakeFromGit, getRecurseForDerivations, getStringIgnoreContext, initThread, isDerivation, isFunctor, match, rawValueType, rtValue, toRawValue, toValue, withEvalStateConduit)
 import Hercules.CNix.Expr.Context (EvalState)
-import qualified Hercules.CNix.Expr.Raw
+import Hercules.CNix.Expr.Raw qualified
 import Hercules.CNix.Expr.Schema (MonadEval, PSObject, dictionaryToMap, fromPSObject, provenance, requireDict, traverseArray, (#.), (#?), (#?!), (#??), ($?), (|!), type (->?), type (.))
-import qualified Hercules.CNix.Expr.Schema as Schema
+import Hercules.CNix.Expr.Schema qualified as Schema
 import Hercules.CNix.Expr.Typed (Value)
 import Hercules.CNix.Std.Vector (StdVector)
-import qualified Hercules.CNix.Std.Vector as Std.Vector
+import Hercules.CNix.Std.Vector qualified as Std.Vector
 import Hercules.CNix.Store.Context (NixStorePathWithOutputs)
 import Hercules.Error
 import Hercules.UserException (UserException (UserException))
 import Katip
 import Protolude hiding (bracket, catch, check, evalState, wait, withAsync, yield)
-import qualified UnliftIO
+import UnliftIO qualified
 import UnliftIO.Async (wait)
 import UnliftIO.Exception (bracket, catch)
 import Prelude ()
@@ -315,12 +315,12 @@
         toValue evalState pso
     else escalateAs UserException =<< liftIO (loadNixFile evalState (toS $ Eval.cwd eval) (coerce $ Eval.gitSource eval))
 
-walkOnPush :: (MonadEval m, MonadUnliftIO m, KatipContext m, MonadThrow m) => EvalEnv -> OnPush.OnPush -> PSObject HerculesCISchema -> ConduitT i Event m ()
+walkOnPush :: (MonadEval m, MonadUnliftIO m, KatipContext m) => EvalEnv -> OnPush.OnPush -> PSObject HerculesCISchema -> ConduitT i Event m ()
 walkOnPush evalEnv onPushParams herculesCI = do
   handler <- herculesCI #?! #onPush >>= requireDict (OnPush.name onPushParams)
   walkHandler evalEnv (OnPush.inputs onPushParams) handler
 
-walkOnSchedule :: (MonadEval m, MonadUnliftIO m, KatipContext m, MonadThrow m) => EvalEnv -> OnSchedule.OnSchedule -> PSObject HerculesCISchema -> ConduitT i Event m ()
+walkOnSchedule :: (MonadEval m, MonadUnliftIO m, KatipContext m) => EvalEnv -> OnSchedule.OnSchedule -> PSObject HerculesCISchema -> ConduitT i Event m ()
 walkOnSchedule evalEnv onScheduleParams herculesCI = do
   handler <- herculesCI #?! #onSchedule >>= requireDict (OnSchedule.name onScheduleParams)
   walkHandler evalEnv (OnSchedule.extraInputs onScheduleParams) handler
@@ -685,7 +685,6 @@
       store = evalEnvStore evalEnv
       evalState = evalEnvState evalEnv
       walk' ::
-        (MonadUnliftIO m, KatipContext m) =>
         -- If True, always walk this attribute set. Only True for the root.
         Bool ->
         -- Attribute path
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs
@@ -27,8 +27,8 @@
 import Hercules.CNix.Expr.Context (NixStorePathWithOutputs)
 import Hercules.CNix.Std.Vector (CStdVector, StdVector)
 import Hercules.CNix.Store.Context (Ref)
-import qualified Language.C.Inline.Cpp as C
-import qualified Language.C.Inline.Cpp.Exception as C
+import Language.C.Inline.Cpp qualified as C
+import Language.C.Inline.Cpp.Exception qualified as C
 import Protolude
 import Prelude ()
 
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore/Context.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore/Context.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore/Context.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore/Context.hs
@@ -9,13 +9,13 @@
   )
 where
 
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Hercules.CNix.Expr.Context (Ref)
 import Hercules.CNix.Std.Vector (stdVectorCtx)
-import qualified Hercules.CNix.Store.Context as Store
-import qualified Language.C.Inline.Context as C
-import qualified Language.C.Inline.Cpp as C
-import qualified Language.C.Types as C
+import Hercules.CNix.Store.Context qualified as Store
+import Language.C.Inline.Context qualified as C
+import Language.C.Inline.Cpp qualified as C
+import Language.C.Types qualified as C
 import Protolude
 
 data HerculesStore
diff --git a/hercules-ci-agent-worker/Hercules/Agent/Worker/STM.hs b/hercules-ci-agent-worker/Hercules/Agent/Worker/STM.hs
--- a/hercules-ci-agent-worker/Hercules/Agent/Worker/STM.hs
+++ b/hercules-ci-agent-worker/Hercules/Agent/Worker/STM.hs
@@ -5,7 +5,7 @@
 import Control.Concurrent.Async
 import Control.Concurrent.STM (TVar, readTVar, writeTVar)
 import Control.Monad.Fix (mfix)
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Protolude
 
 asyncIfSTM ::
diff --git a/hercules-ci-agent.cabal b/hercules-ci-agent.cabal
--- a/hercules-ci-agent.cabal
+++ b/hercules-ci-agent.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.4
 
 name:           hercules-ci-agent
-version:        0.9.11
+version:        0.9.12
 synopsis:       Runs Continuous Integration tasks on your machines
 category:       Nix, CI, Testing, DevOps
 homepage:       https://docs.hercules-ci.com
@@ -21,43 +21,71 @@
 data-files:
     data/default-herculesCI-for-flake.nix
 
--- Deprecated
-flag nix-2_4
-  description: Build for Nix >=2.4*
-  default: True
+flag nix-2_15
+  description: Build for Nix >=2.15.0
+  default: False
 
-flag nix-2_5
-  description: Build for Nix >=2.5*
+flag ide
+  description: Whether to enable IDE workarounds. You shouldn't need this.
   default: False
 
 source-repository head
   type: git
   location: https://github.com/hercules-ci/hercules-ci-agent
 
+common hs
+  default-extensions: 
+    NoImplicitPrelude
+    DeriveGeneric
+    DeriveTraversable
+    DerivingStrategies
+    DisambiguateRecordFields
+    FlexibleContexts
+    ImportQualifiedPost
+    InstanceSigs
+    LambdaCase
+    MultiParamTypeClasses
+    NumericUnderscores
+    OverloadedRecordDot
+    OverloadedStrings
+    RankNTypes
+    TupleSections
+    TypeApplications
+    TypeOperators
+
+  ghc-options: -Wall -fwarn-tabs -fwarn-unused-imports -fwarn-missing-signatures -fwarn-name-shadowing -fwarn-incomplete-patterns -Werror=incomplete-patterns -Werror=missing-fields
+
+common rts
+  ghc-options: -threaded -rtsopts "-with-rtsopts=-maxN8 -qg"
+
 -- match the C++ language standard Nix is using
 common cxx-opts
+  if flag(nix-2_15)
+    cxx-options:
+      -std=c++2a
+  else
+    cxx-options:
+      -std=c++17
+
   cxx-options:
-    -std=c++17
     -Wall
   extra-libraries: stdc++
 
-  if flag(nix-2_5)
-    cxx-options:
-      -DNIX_2_5
-    cpp-options:
-      -DNIX_2_5
-
   if os(darwin)
     -- avoid https://gitlab.haskell.org/ghc/ghc/issues/11829
     ld-options:  -Wl,-keep_dwarf_unwind
-    -- llvm severe warnings
-    cxx-options: -Werror=abstract-final-class
 
   if impl(ghc >= 8.10)
     ghc-options:
-      -optcxx-std=c++17
       -optcxx-Wall
+    if flag(nix-2_15)
+      ghc-options:
+        -optcxx-std=c++2a
+    else
+      ghc-options:
+        -optcxx-std=c++17
   else
+    -- Remove soon
     ghc-options:
       -optc-std=c++17
       -optc-Wall
@@ -72,6 +100,7 @@
 
 
 library
+  import: hs
   exposed-modules:
       Data.Fixed.Extras
       Data.Time.Extras
@@ -105,6 +134,7 @@
       Hercules.UserException
       Data.Conduit.Extras
       Data.Conduit.Katip.Orphans
+  other-modules:
       Paths_hercules_ci_agent
   autogen-modules:
       Paths_hercules_ci_agent
@@ -159,6 +189,7 @@
   default-language: Haskell2010
 
 executable hercules-ci-agent
+  import: hs, rts
   main-is: Main.hs
   other-modules:
       Data.Functor.Partitioner
@@ -195,6 +226,9 @@
       Hercules.Agent.SecureDirectory
       Hercules.Agent.ServiceInfo
       Hercules.Agent.Token
+      Paths_hercules_ci_agent
+  autogen-modules:
+      Paths_hercules_ci_agent
   hs-source-dirs:
       hercules-ci-agent
   default-extensions: DeriveGeneric DeriveTraversable DisambiguateRecordFields FlexibleContexts InstanceSigs LambdaCase MultiParamTypeClasses NoImplicitPrelude OverloadedStrings RankNTypes TupleSections TypeApplications TypeOperators
@@ -208,7 +242,11 @@
     , binary
     , binary-conduit
     , bytestring
-    , cachix
+      -- cachix 1.4 and 1.4.1 have known issues on multi-user Nix systems.
+      -- hercules-ci-agent will upgrade its dependency when either the solution
+      -- matures, or a better solution is implemented: new Nix libstore bindings
+      -- that support static linking, as they require.
+    , cachix <1.4 || >=1.5
     , cachix-api
     , hercules-ci-cnix-store
     , conduit
@@ -220,8 +258,8 @@
     , filepath
     , hercules-ci-agent
     , hercules-ci-api
-    , hercules-ci-api-core == 0.1.5.0
-    , hercules-ci-api-agent == 0.5.0.0
+    , hercules-ci-api-core == 0.1.5.1
+    , hercules-ci-api-agent == 0.5.0.1
     , hostname
     , http-client
     , http-client-tls
@@ -263,7 +301,7 @@
   default-language: Haskell2010
 
 executable hercules-ci-agent-worker
-  import: cxx-opts
+  import: cxx-opts, hs
   main-is: Main.hs
   other-modules:
       Hercules.Agent.Worker
@@ -303,8 +341,9 @@
   include-dirs:
       cbits
       cbits/nix-2.4
-  extra-libraries:
-      boost_context
+  if ! flag(ide)
+    extra-libraries:
+        boost_context
   build-depends:
       aeson
     , async
@@ -354,7 +393,8 @@
     , nix-main >= 2.0
   default-language: Haskell2010
 
-test-suite hercules-test
+test-suite hercules-ci-agent-unit-tests
+  import: hs, rts
   type: exitcode-stdio-1.0
   main-is: TestMain.hs
   other-modules:
@@ -373,6 +413,9 @@
       Hercules.Secrets
       Hercules.SecretsSpec
       Spec
+      Paths_hercules_ci_agent
+  autogen-modules:
+      Paths_hercules_ci_agent
   hs-source-dirs:
       src
       test
@@ -411,6 +454,9 @@
     , text
     , transformers-base
     , unliftio-core
+    , vector
+  build-tool-depends:
+      hspec-discover:hspec-discover
   default-language: Haskell2010
 
 executable hercules-ci-nix-daemon
diff --git a/hercules-ci-agent/Data/Functor/Partitioner.hs b/hercules-ci-agent/Data/Functor/Partitioner.hs
--- a/hercules-ci-agent/Data/Functor/Partitioner.hs
+++ b/hercules-ci-agent/Data/Functor/Partitioner.hs
@@ -16,7 +16,7 @@
 where
 
 import Data.Coerce
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Protolude
 
 -- TODO: Profunctor
diff --git a/hercules-ci-agent/Data/Map/Extras/Hercules.hs b/hercules-ci-agent/Data/Map/Extras/Hercules.hs
--- a/hercules-ci-agent/Data/Map/Extras/Hercules.hs
+++ b/hercules-ci-agent/Data/Map/Extras/Hercules.hs
@@ -1,9 +1,9 @@
 module Data.Map.Extras.Hercules where
 
 import Control.Arrow ((&&&))
-import qualified Data.List as L
-import qualified Data.List.NonEmpty as NEL
-import qualified Data.Map as M
+import Data.List qualified as L
+import Data.List.NonEmpty qualified as NEL
+import Data.Map qualified as M
 import Protolude hiding (groupBy)
 
 groupOn :: Ord k => (a -> k) -> [a] -> M.Map k [a]
diff --git a/hercules-ci-agent/Hercules/Agent.hs b/hercules-ci-agent/Hercules/Agent.hs
--- a/hercules-ci-agent/Hercules/Agent.hs
+++ b/hercules-ci-agent/Hercules/Agent.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE CPP #-}
 
 module Hercules.Agent
   ( main,
@@ -13,51 +14,54 @@
 import Control.Concurrent.STM.TChan
 import Control.Exception.Lifted (bracket)
 import Control.Monad.IO.Unlift (MonadUnliftIO)
-import qualified Data.Aeson as A
-import qualified Data.Map as M
+import Data.Aeson qualified as A
+import Data.Map qualified as M
 import Data.Time (getCurrentTime)
-import qualified Data.UUID.V4 as UUID
-import qualified Hercules.API.Agent.Build.BuildTask as BuildTask
-import qualified Hercules.API.Agent.Effect.EffectTask as EffectTask
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask as EvaluateTask
-import qualified Hercules.API.Agent.LifeCycle as LifeCycle
+import Data.UUID.V4 qualified as UUID
+import Hercules.API.Agent.Build.BuildTask qualified as BuildTask
+import Hercules.API.Agent.Effect.EffectTask qualified as EffectTask
+import Hercules.API.Agent.Evaluate.EvaluateTask qualified as EvaluateTask
+import Hercules.API.Agent.LifeCycle qualified as LifeCycle
 import Hercules.API.Agent.LifeCycle.StartInfo (tasksInProgress)
-import qualified Hercules.API.Agent.LifeCycle.StartInfo as StartInfo
-import qualified Hercules.API.Agent.Socket.AgentPayload as AgentPayload
-import qualified Hercules.API.Agent.Socket.ServicePayload as ServicePayload
+import Hercules.API.Agent.LifeCycle.StartInfo qualified as StartInfo
+import Hercules.API.Agent.Socket.AgentPayload qualified as AgentPayload
+import Hercules.API.Agent.Socket.ServicePayload qualified as ServicePayload
 import Hercules.API.Agent.Tasks
   ( tasksSetStatus,
   )
 import Hercules.API.Id (Id (Id))
 import Hercules.API.Servant (noContent)
 import Hercules.API.Task (Task)
-import qualified Hercules.API.Task as Task
-import qualified Hercules.API.TaskStatus as TaskStatus
+import Hercules.API.Task qualified as Task
+import Hercules.API.TaskStatus qualified as TaskStatus
 import Hercules.Agent.AgentSocket (withAgentSocket)
-import qualified Hercules.Agent.Build as Build
+import Hercules.Agent.Build qualified as Build
 import Hercules.Agent.CabalInfo (herculesAgentVersion)
-import qualified Hercules.Agent.Cache as Cache
-import qualified Hercules.Agent.Cachix.Env as Cachix.Env
+import Hercules.Agent.Cache qualified as Cache
+#if ! MIN_VERSION_cachix(1, 4, 0) || MIN_VERSION_cachix(1, 5, 0)
+import Hercules.Agent.Cachix.Env qualified as Cachix.Env
+#endif
 import Hercules.Agent.Client
   ( lifeCycleClient,
     tasksClient,
   )
-import qualified Hercules.Agent.Config as Config
-import qualified Hercules.Agent.Effect as Effect
+import Hercules.Agent.Config qualified as Config
+import Hercules.Agent.Effect qualified as Effect
 import Hercules.Agent.Env
   ( App,
     runHerculesClient,
   )
-import qualified Hercules.Agent.Env as Env
+import Hercules.Agent.Env qualified as Env
 import Hercules.Agent.EnvironmentInfo (extractAgentInfo)
-import qualified Hercules.Agent.Evaluate as Evaluate
-import qualified Hercules.Agent.Init as Init
+import Hercules.Agent.Evaluate qualified as Evaluate
+import Hercules.Agent.Init qualified as Init
 import Hercules.Agent.Log
-import qualified Hercules.Agent.Netrc as Netrc
-import qualified Hercules.Agent.Options as Options
+import Hercules.Agent.Netrc qualified as Netrc
+import Hercules.Agent.Options qualified as Options
 import Hercules.Agent.STM
 import Hercules.Agent.Socket as Socket
 import Hercules.Agent.Token (withAgentToken)
+import Hercules.CNix.Store qualified as CNix.Store
 import Hercules.Error
   ( cap,
     exponential,
@@ -77,7 +81,7 @@
   )
 import System.Posix.Resource
 import UnliftIO.Exception (catch)
-import qualified Prelude
+import Prelude qualified
 
 main :: IO ()
 main = do
@@ -86,10 +90,10 @@
   cfg <- Config.finalizeConfig cfgPath =<< Config.readConfig cfgPath
   Init.initCNix cfg
   Init.setupLogging cfg $ \logEnv -> do
-    env <- Init.newEnv cfg logEnv
-    case Options.mode opts of
-      Options.Run -> run env cfg
-      Options.Test -> testConfiguration env cfg
+    Init.withEnv cfg logEnv $ \env -> do
+      case Options.mode opts of
+        Options.Run -> run env cfg
+        Options.Test -> testConfiguration env cfg
 
 testConfiguration :: Env.Env -> Config.FinalConfig -> IO ()
 testConfiguration _env _cfg = do
@@ -119,9 +123,8 @@
                       ServicePayload.StartEvaluation evalTask ->
                         launchTask tasks socket (Task.upcastId $ EvaluateTask.id evalTask) do
                           Netrc.withNixNetrc $ Cache.withCaches do
-                            -- TODO move the store directly under env
-                            store <- asks (Cachix.Env.nixStore . Env.cachixEnv)
-                            Evaluate.performEvaluation store evalTask
+                            CNix.Store.withStore \store -> do
+                              Evaluate.performEvaluation store evalTask
                             pure $ TaskStatus.Successful ()
                       ServicePayload.StartBuild buildTask ->
                         launchTask tasks socket (Task.upcastId $ BuildTask.id buildTask) do
diff --git a/hercules-ci-agent/Hercules/Agent/AgentSocket.hs b/hercules-ci-agent/Hercules/Agent/AgentSocket.hs
--- a/hercules-ci-agent/Hercules/Agent/AgentSocket.hs
+++ b/hercules-ci-agent/Hercules/Agent/AgentSocket.hs
@@ -1,20 +1,20 @@
 module Hercules.Agent.AgentSocket (withAgentSocket) where
 
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Hercules.API.Agent.LifeCycle.StartInfo (Hello, tasksInProgress)
 import Hercules.API.Agent.Socket.AgentPayload (AgentPayload)
-import qualified Hercules.API.Agent.Socket.AgentPayload as AgentPayload
+import Hercules.API.Agent.Socket.AgentPayload qualified as AgentPayload
 import Hercules.API.Agent.Socket.ServicePayload (ServicePayload)
-import qualified Hercules.API.Agent.Socket.ServicePayload as ServicePayload
+import Hercules.API.Agent.Socket.ServicePayload qualified as ServicePayload
 import Hercules.API.Id (Id)
 import Hercules.API.Task (Task)
-import qualified Hercules.API.Task as Task
+import Hercules.API.Task qualified as Task
 import Hercules.Agent.Env
   ( App,
   )
-import qualified Hercules.Agent.Env as Agent.Env
+import Hercules.Agent.Env qualified as Agent.Env
 import Hercules.Agent.STM (TVar, readTVarIO)
-import qualified Hercules.Agent.ServiceInfo as ServiceInfo
+import Hercules.Agent.ServiceInfo qualified as ServiceInfo
 import Hercules.Agent.Socket as Socket
 import Protolude hiding
   ( bracket,
@@ -25,7 +25,7 @@
     retry,
     withMVar,
   )
-import qualified Servant.Auth.Client
+import Servant.Auth.Client qualified
 
 withAgentSocket :: Hello -> TVar (Map (Id (Task Task.Any)) b) -> (Socket ServicePayload AgentPayload -> App a) -> App a
 withAgentSocket hello tasks f = do
diff --git a/hercules-ci-agent/Hercules/Agent/Bag.hs b/hercules-ci-agent/Hercules/Agent/Bag.hs
--- a/hercules-ci-agent/Hercules/Agent/Bag.hs
+++ b/hercules-ci-agent/Hercules/Agent/Bag.hs
@@ -10,7 +10,7 @@
 where
 
 import Data.Aeson
-import qualified Data.Aeson.KeyMap as AK
+import Data.Aeson.KeyMap qualified as AK
 import Data.Aeson.Types
 import Data.Functor.Compose
 import Data.Functor.Partitioner hiding
diff --git a/hercules-ci-agent/Hercules/Agent/Build.hs b/hercules-ci-agent/Hercules/Agent/Build.hs
--- a/hercules-ci-agent/Hercules/Agent/Build.hs
+++ b/hercules-ci-agent/Hercules/Agent/Build.hs
@@ -1,42 +1,45 @@
+{-# LANGUAGE CPP #-}
 module Hercules.Agent.Build where
 
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.IORef.Lifted
-import qualified Data.Map as M
-import qualified Hercules.API.Agent.Build as API.Build
-import qualified Hercules.API.Agent.Build.BuildEvent as BuildEvent
+import Data.Map qualified as M
+import Hercules.API.Agent.Build qualified as API.Build
+import Hercules.API.Agent.Build.BuildEvent qualified as BuildEvent
 import Hercules.API.Agent.Build.BuildEvent.OutputInfo
   ( OutputInfo,
   )
-import qualified Hercules.API.Agent.Build.BuildEvent.OutputInfo as OutputInfo
-import qualified Hercules.API.Agent.Build.BuildEvent.Pushed as Pushed
+import Hercules.API.Agent.Build.BuildEvent.OutputInfo qualified as OutputInfo
+import Hercules.API.Agent.Build.BuildEvent.Pushed qualified as Pushed
 import Hercules.API.Agent.Build.BuildTask
   ( BuildTask,
   )
-import qualified Hercules.API.Agent.Build.BuildTask as BuildTask
+import Hercules.API.Agent.Build.BuildTask qualified as BuildTask
 import Hercules.API.Servant (noContent)
 import Hercules.API.TaskStatus (TaskStatus)
-import qualified Hercules.API.TaskStatus as TaskStatus
-import qualified Hercules.Agent.Cache as Agent.Cache
-import qualified Hercules.Agent.Cachix.Env as Cachix.Env
-import qualified Hercules.Agent.Client
-import qualified Hercules.Agent.Config as Config
+import Hercules.API.TaskStatus qualified as TaskStatus
+import Hercules.Agent.Cache qualified as Agent.Cache
+#if ! MIN_VERSION_cachix(1, 4, 0) || MIN_VERSION_cachix(1, 5, 0)
+import Hercules.Agent.Cachix.Env qualified as Cachix.Env
+#endif
+import Hercules.Agent.Client qualified
+import Hercules.Agent.Config qualified as Config
 import Hercules.Agent.Env
-import qualified Hercules.Agent.Env as Env
+import Hercules.Agent.Env qualified as Env
 import Hercules.Agent.Log
-import qualified Hercules.Agent.Nix as Nix
+import Hercules.Agent.Nix qualified as Nix
 import Hercules.Agent.Sensitive (Sensitive (Sensitive))
-import qualified Hercules.Agent.ServiceInfo as ServiceInfo
+import Hercules.Agent.ServiceInfo qualified as ServiceInfo
 import Hercules.Agent.WorkerProcess
-import qualified Hercules.Agent.WorkerProcess as WorkerProcess
-import qualified Hercules.Agent.WorkerProtocol.Command as Command
-import qualified Hercules.Agent.WorkerProtocol.Command.Build as Command.Build
-import qualified Hercules.Agent.WorkerProtocol.Event as Event
-import qualified Hercules.Agent.WorkerProtocol.Event.BuildResult as BuildResult
-import qualified Hercules.Agent.WorkerProtocol.LogSettings as LogSettings
-import qualified Hercules.CNix.Store as CNix
+import Hercules.Agent.WorkerProcess qualified as WorkerProcess
+import Hercules.Agent.WorkerProtocol.Command qualified as Command
+import Hercules.Agent.WorkerProtocol.Command.Build qualified as Command.Build
+import Hercules.Agent.WorkerProtocol.Event qualified as Event
+import Hercules.Agent.WorkerProtocol.Event.BuildResult qualified as BuildResult
+import Hercules.Agent.WorkerProtocol.LogSettings qualified as LogSettings
+import Hercules.CNix.Store qualified as CNix
 import Hercules.Error (defaultRetry)
-import qualified Network.URI
+import Network.URI qualified
 import Protolude
 import System.Process
 
@@ -59,7 +62,7 @@
         (System.Process.proc workerExe opts)
           { env = Just workerEnv,
             close_fds = True,
-            cwd = Just "/"
+            cwd = Nothing
           }
       writeEvent :: Event.Event -> App ()
       writeEvent event = case event of
@@ -103,8 +106,11 @@
     Just BuildResult.BuildSuccess {outputs = outs'} -> do
       let outs = convertOutputs (BuildTask.derivationPath buildTask) outs'
       reportOutputInfos buildTask outs
-      store <- asks (Cachix.Env.nixStore . Env.cachixEnv)
-      push store buildTask outs
+#if MIN_VERSION_cachix(1, 4, 0) && ! MIN_VERSION_cachix(1, 5, 0)
+      CNix.withStore $ \store -> push store buildTask outs
+#else
+      asks (Cachix.Env.store . Env.cachixEnv) >>= \store -> push store buildTask outs
+#endif
       reportSuccess buildTask
       pure $ TaskStatus.Successful ()
     Just BuildResult.BuildFailure {} -> pure $ TaskStatus.Terminated ()
@@ -128,7 +134,7 @@
   forM_ caches $ \cache -> do
     -- TODO preserve StorePath instead
     storePaths <- liftIO $ for paths (CNix.parseStorePath store . encodeUtf8)
-    Agent.Cache.push cache storePaths 4
+    Agent.Cache.push store cache storePaths 4
     emitEvents buildTask [BuildEvent.Pushed $ Pushed.Pushed {cache = cache}]
 
 reportSuccess :: BuildTask -> App ()
diff --git a/hercules-ci-agent/Hercules/Agent/Cache.hs b/hercules-ci-agent/Hercules/Agent/Cache.hs
--- a/hercules-ci-agent/Hercules/Agent/Cache.hs
+++ b/hercules-ci-agent/Hercules/Agent/Cache.hs
@@ -2,22 +2,22 @@
 
 module Hercules.Agent.Cache where
 
-import qualified Data.Map as M
-import qualified Data.Text as T
+import Data.Map qualified as M
+import Data.Text qualified as T
 import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
-import qualified Hercules.Agent.Cachix as Cachix
-import qualified Hercules.Agent.Config.BinaryCaches as Config
+import Hercules.Agent.Cachix qualified as Cachix
+import Hercules.Agent.Config.BinaryCaches qualified as Config
 import Hercules.Agent.Env (App)
-import qualified Hercules.Agent.Env as Env
-import qualified Hercules.Agent.Netrc as Netrc
-import qualified Hercules.Agent.Nix as Nix
-import qualified Hercules.CNix as CNix
+import Hercules.Agent.Env qualified as Env
+import Hercules.Agent.Netrc qualified as Netrc
+import Hercules.Agent.Nix qualified as Nix
+import Hercules.CNix qualified as CNix
 import Hercules.CNix.Std.Set (StdSet, toListFP)
-import qualified Hercules.CNix.Std.Set as Std.Set
+import Hercules.CNix.Std.Set qualified as Std.Set
 import Hercules.CNix.Store (StorePath)
-import qualified Hercules.CNix.Store as Store
+import Hercules.CNix.Store qualified as Store
 import Hercules.Error (defaultRetry)
-import qualified Hercules.Formats.NixCache as NixCache
+import Hercules.Formats.NixCache qualified as NixCache
 import Katip
 import Protolude
 
@@ -39,6 +39,8 @@
     m
 
 push ::
+  -- | Nix Store
+  CNix.Store ->
   -- | Cache name
   Text ->
   -- | Paths, which do not have to form a closure
@@ -46,14 +48,14 @@
   -- | Number of concurrent upload threads
   Int ->
   App ()
-push cacheName paths concurrency = katipAddNamespace "Push" $ katipAddContext (sl "cacheName" cacheName) do
+push store cacheName paths concurrency = katipAddNamespace "Push" $ katipAddContext (sl "cacheName" cacheName) do
   caches <- asks Env.binaryCaches
   let maybeNix =
         Config.nixCaches caches & M.lookup cacheName & fmap \cache ->
           nixPush cache paths concurrency
       maybeCachix =
         Config.cachixCaches caches & M.lookup cacheName & fmap \_cache ->
-          Cachix.push cacheName paths concurrency
+          Cachix.push store cacheName paths concurrency
       failNothing =
         throwIO $ FatalError $ "Agent does not have a binary cache named " <> show cacheName <> " in its configuration."
   fromMaybe failNothing (maybeNix <|> maybeCachix)
diff --git a/hercules-ci-agent/Hercules/Agent/Cachix.hs b/hercules-ci-agent/Hercules/Agent/Cachix.hs
--- a/hercules-ci-agent/Hercules/Agent/Cachix.hs
+++ b/hercules-ci-agent/Hercules/Agent/Cachix.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+
 module Hercules.Agent.Cachix
   ( module Hercules.Agent.Cachix,
     activePushCaches,
@@ -7,6 +8,11 @@
 
 import qualified Cachix.Client.Push as Cachix.Push
 import Cachix.Types.BinaryCache (CompressionMethod(XZ))
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+import qualified Cachix.Client.Store
+import qualified Cachix.Client.Store as Cachix
+#endif
+import qualified Data.Conduit as Conduit
 import Control.Monad.IO.Unlift
 import qualified Data.Map as M
 import qualified Hercules.Agent.Cachix.Env as Agent.Cachix
@@ -18,12 +24,13 @@
 import Hercules.Error
 import qualified Hercules.Formats.CachixCache as CachixCache
 import Protolude
+import qualified Hercules.CNix as CNix
 
-push :: Text -> [StorePath] -> Int -> App ()
-push cache paths workers = withNamedContext "cache" cache $ do
+push :: CNix.Store -> Text -> [StorePath] -> Int -> App ()
+push nixStore cache paths workers = withNamedContext "cache" cache $ do
   Agent.Cachix.Env
     { pushCaches = pushCaches,
-      nixStore = nixStore,
+      store = cachixStore,
       clientEnv = clientEnv
     } <-
     asks Agent.Cachix.getEnv
@@ -36,10 +43,17 @@
         Cachix.Push.PushParams
           { pushParamsName = Agent.Cachix.pushCacheName pushCache,
             pushParamsSecret = Agent.Cachix.pushCacheSecret pushCache,
-            pushParamsStore = nixStore,
+            pushParamsStore = cachixStore,
+#if MIN_VERSION_cachix(1,6,0)
+            pushOnClosureAttempt = \_ missing -> return missing,
+#endif
             pushParamsClientEnv = clientEnv,
             pushParamsStrategy = \storePath ->
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+              let ctx = withNamedContext "path" (Cachix.getPath storePath)
+#else
               let ctx = withNamedContext "path" (show storePath :: Text)
+#endif
                in Cachix.Push.PushStrategy
                     { onAlreadyPresent = pass,
                       onAttempt = \retryStatus size ->
@@ -60,14 +74,33 @@
 #else
                       withXzipCompressor = Cachix.Push.defaultWithXzipCompressor,
 #endif
+#if MIN_VERSION_cachix(1,6,0)
+                      onUncompressedNARStream = \_ _ -> Conduit.awaitForever Conduit.yield,
+#endif
                       omitDeriver = False
                     }
           }
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+  paths' <- paths & traverse (convertPath nixStore)
+#else
+  let paths' = paths
+#endif
   void $
     Cachix.Push.pushClosure
       (\f l -> liftIO $ Cachix.Push.mapConcurrentlyBounded workers (fmap (unliftIO ul) f) l)
       pushParams
-      paths
+      paths'
+
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+
+-- This assumes that the store is not relocated, as cachix does not support that at the time of writing.
+convertPath :: CNix.Store -> StorePath -> App Cachix.Client.Store.StorePath
+convertPath store storePath = do
+  storePathBytes <- liftIO $ CNix.storePathToPath store storePath
+  let storePathText = decodeUtf8With lenientDecode storePathBytes
+  pure (Cachix.Client.Store.StorePath storePathText)
+
+#endif
 
 getNetrcLines :: App [Text]
 getNetrcLines = asks (Agent.Cachix.netrcLines . Agent.Env.cachixEnv)
diff --git a/hercules-ci-agent/Hercules/Agent/Cachix/Env.hs b/hercules-ci-agent/Hercules/Agent/Cachix/Env.hs
--- a/hercules-ci-agent/Hercules/Agent/Cachix/Env.hs
+++ b/hercules-ci-agent/Hercules/Agent/Cachix/Env.hs
@@ -1,11 +1,27 @@
+{-# LANGUAGE CPP #-}
+
 module Hercules.Agent.Cachix.Env where
 
-import qualified Cachix.Client.Push as Cachix
-import Hercules.CNix.Store (Store)
+import Cachix.Client.Push qualified as Cachix
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+import Cachix.Client.Store qualified
+
+#else
+import Hercules.CNix.Store qualified
+
+#endif
 import Hercules.Formats.CachixCache (CachixCache)
 import Protolude
 import Servant.Client (ClientEnv)
 
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+type CachixStore = Cachix.Client.Store.Store
+
+#else
+type CachixStore = Hercules.CNix.Store.Store
+
+#endif
+
 data PushCache = PushCache
   { pushCacheName :: Text,
     pushCacheSecret :: Cachix.PushSecret
@@ -15,7 +31,7 @@
   { pushCaches :: Map Text PushCache,
     cacheKeys :: Map Text CachixCache,
     netrcLines :: [Text],
-    nixStore :: Store,
+    store :: CachixStore,
     clientEnv :: ClientEnv
   }
 
diff --git a/hercules-ci-agent/Hercules/Agent/Cachix/Info.hs b/hercules-ci-agent/Hercules/Agent/Cachix/Info.hs
--- a/hercules-ci-agent/Hercules/Agent/Cachix/Info.hs
+++ b/hercules-ci-agent/Hercules/Agent/Cachix/Info.hs
@@ -1,6 +1,6 @@
 module Hercules.Agent.Cachix.Info where
 
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Hercules.Agent.Cachix.Env
 import Protolude
 
diff --git a/hercules-ci-agent/Hercules/Agent/Cachix/Init.hs b/hercules-ci-agent/Hercules/Agent/Cachix/Init.hs
--- a/hercules-ci-agent/Hercules/Agent/Cachix/Init.hs
+++ b/hercules-ci-agent/Hercules/Agent/Cachix/Init.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
 
@@ -8,21 +9,32 @@
 #else
 import Cachix.Client.Env (cachixVersion)
 #endif
-import qualified Cachix.Client.Push as Cachix.Push
-import qualified Cachix.Client.Secrets as Cachix.Secrets
+
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+import Cachix.Client.Store qualified as Cachix
+import Control.Monad.IO.Unlift (UnliftIO (UnliftIO), askUnliftIO)
+import Hercules.CNix.Settings qualified as CNix
+
+#else
+import Hercules.CNix.Store (openStore)
+
+#endif
+import Cachix.Client.Push qualified as Cachix.Push
+import Cachix.Client.Secrets qualified as Cachix.Secrets
 import Cachix.Client.URI (defaultCachixBaseUrl)
-import qualified Data.Map as M
+import Control.Monad.IO.Unlift (MonadUnliftIO)
+import Data.Map qualified as M
 import Hercules.Agent.Cachix.Env as Env
-import qualified Hercules.Agent.Config as Config
-import Hercules.CNix.Store (openStore)
+import Hercules.Agent.Config qualified as Config
 import Hercules.Error
-import qualified Hercules.Formats.CachixCache as CachixCache
-import qualified Katip as K
+import Hercules.Formats.CachixCache qualified as CachixCache
+import Katip (KatipContext)
+import Katip qualified as K
 import Network.HTTP.Client (ManagerSettings (managerModifyRequest, managerResponseTimeout), responseTimeoutNone)
 import Network.HTTP.Client.TLS (newTlsManagerWith, tlsManagerSettings)
 import Network.HTTP.Simple (setRequestHeader)
 import Protolude
-import qualified Servant.Auth.Client
+import Servant.Auth.Client qualified
 import Servant.Client (mkClientEnv)
 
 -- TODO use from lib after cachix >0.3.5 + https://github.com/cachix/cachix/pull/274
@@ -34,22 +46,46 @@
       managerModifyRequest = return . setRequestHeader "User-Agent" [encodeUtf8 cachixVersion]
     }
 
-newEnv :: Config.FinalConfig -> Map Text CachixCache.CachixCache -> K.KatipContextT IO Env.Env
-newEnv _config cks = do
+withEnv :: (MonadUnliftIO m, KatipContext m) => Config.FinalConfig -> Map Text CachixCache.CachixCache -> (Env.Env -> m a) -> m a
+withEnv _config cks continue = do
   -- FIXME: sl doesn't work??
   K.katipAddContext (K.sl "caches" (M.keys cks)) $
     K.logLocM K.DebugS ("Cachix init " <> K.logStr (show (M.keys cks) :: Text))
   pcs <- liftIO $ toPushCaches cks
-  store <- liftIO openStore
   httpManager <- newTlsManagerWith customManagerSettings
-  pure
-    Env.Env
-      { pushCaches = pcs,
-        netrcLines = toNetrcLines cks,
-        cacheKeys = cks,
-        nixStore = store,
-        clientEnv = mkClientEnv httpManager defaultCachixBaseUrl
-      }
+
+#if MIN_VERSION_cachix(1,4,0) && ! MIN_VERSION_cachix(1,5,0)
+  UnliftIO unlift <- askUnliftIO
+  useWAL <- liftIO CNix.getUseSQLiteWAL
+
+  liftIO do
+    Cachix.withLocalStore
+      Cachix.LocalStoreOptions
+        { storePrefix = "/nix",
+          useSqliteWAL = useWAL
+        }
+      \store -> unlift do
+        continue
+          Env.Env
+            { pushCaches = pcs,
+              netrcLines = toNetrcLines cks,
+              cacheKeys = cks,
+              store = store,
+              clientEnv = mkClientEnv httpManager defaultCachixBaseUrl
+            }
+#else
+  env <- do
+    store <- liftIO openStore
+    pure
+      Env.Env
+        { pushCaches = pcs,
+          netrcLines = toNetrcLines cks,
+          cacheKeys = cks,
+          store = store,
+          clientEnv = mkClientEnv httpManager defaultCachixBaseUrl
+        }
+  continue env
+#endif
 
 toNetrcLines :: Map Text CachixCache.CachixCache -> [Text]
 toNetrcLines = concatMap toNetrcLine . M.toList
diff --git a/hercules-ci-agent/Hercules/Agent/Client.hs b/hercules-ci-agent/Hercules/Agent/Client.hs
--- a/hercules-ci-agent/Hercules/Agent/Client.hs
+++ b/hercules-ci-agent/Hercules/Agent/Client.hs
@@ -29,7 +29,7 @@
 import Servant.Auth.Client ()
 import Servant.Client.Generic (AsClientT)
 import Servant.Client.Streaming (ClientM)
-import qualified Servant.Client.Streaming
+import Servant.Client.Streaming qualified
 
 -- | Bad instance to make it the client for State api compile. GHC seems to pick
 -- the wrong overlappable instance.
diff --git a/hercules-ci-agent/Hercules/Agent/Config.hs b/hercules-ci-agent/Hercules/Agent/Config.hs
--- a/hercules-ci-agent/Hercules/Agent/Config.hs
+++ b/hercules-ci-agent/Hercules/Agent/Config.hs
@@ -14,15 +14,15 @@
   )
 where
 
-import qualified Data.Aeson as A
-import qualified Data.Aeson.KeyMap as AK
+import Data.Aeson qualified as A
+import Data.Aeson.KeyMap qualified as AK
 import Data.Scientific (floatingOrInteger, fromFloatDigits)
-import qualified Data.Vector as V
+import Data.Vector qualified as V
 import GHC.Conc (getNumProcessors)
 import Hercules.CNix.Verbosity (Verbosity (..))
 import Katip (Severity (..))
 import Protolude hiding (to)
-import qualified System.Environment
+import System.Environment qualified
 import System.FilePath ((</>))
 import Toml
 
diff --git a/hercules-ci-agent/Hercules/Agent/Config/BinaryCaches.hs b/hercules-ci-agent/Hercules/Agent/Config/BinaryCaches.hs
--- a/hercules-ci-agent/Hercules/Agent/Config/BinaryCaches.hs
+++ b/hercules-ci-agent/Hercules/Agent/Config/BinaryCaches.hs
@@ -9,8 +9,8 @@
 
 import Control.Exception.Lifted (catchJust)
 import Data.Aeson
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.Map as M
+import Data.ByteString.Lazy qualified as BL
+import Data.Map qualified as M
 import Hercules.Agent.Bag
 import Hercules.Agent.Config
 import Hercules.Agent.Log
diff --git a/hercules-ci-agent/Hercules/Agent/Effect.hs b/hercules-ci-agent/Hercules/Agent/Effect.hs
--- a/hercules-ci-agent/Hercules/Agent/Effect.hs
+++ b/hercules-ci-agent/Hercules/Agent/Effect.hs
@@ -1,30 +1,30 @@
 module Hercules.Agent.Effect where
 
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.IORef
-import qualified Data.Map as M
-import qualified Hercules.API.Agent.Effect.EffectTask as EffectTask
+import Data.Map qualified as M
+import Hercules.API.Agent.Effect.EffectTask qualified as EffectTask
 import Hercules.API.TaskStatus (TaskStatus)
-import qualified Hercules.API.TaskStatus as TaskStatus
-import qualified Hercules.Agent.Config as Config
+import Hercules.API.TaskStatus qualified as TaskStatus
+import Hercules.Agent.Config qualified as Config
 import Hercules.Agent.Env hiding (config)
-import qualified Hercules.Agent.Env as Env
+import Hercules.Agent.Env qualified as Env
 import Hercules.Agent.Files
 import Hercules.Agent.Log
-import qualified Hercules.Agent.Nix as Nix
+import Hercules.Agent.Nix qualified as Nix
 import Hercules.Agent.Sensitive (Sensitive (Sensitive))
-import qualified Hercules.Agent.ServiceInfo as ServiceInfo
+import Hercules.Agent.ServiceInfo qualified as ServiceInfo
 import Hercules.Agent.WorkerProcess
-import qualified Hercules.Agent.WorkerProcess as WorkerProcess
-import qualified Hercules.Agent.WorkerProtocol.Command as Command
-import qualified Hercules.Agent.WorkerProtocol.Command.Effect as Command.Effect
-import qualified Hercules.Agent.WorkerProtocol.Event as Event
-import qualified Hercules.Agent.WorkerProtocol.LogSettings as LogSettings
+import Hercules.Agent.WorkerProcess qualified as WorkerProcess
+import Hercules.Agent.WorkerProtocol.Command qualified as Command
+import Hercules.Agent.WorkerProtocol.Command.Effect qualified as Command.Effect
+import Hercules.Agent.WorkerProtocol.Event qualified as Event
+import Hercules.Agent.WorkerProtocol.LogSettings qualified as LogSettings
 import Hercules.Agent.WorkerProtocol.ViaJSON (ViaJSON (ViaJSON))
-import qualified Hercules.Secrets as Secrets
-import qualified Network.URI
+import Hercules.Secrets qualified as Secrets
+import Network.URI qualified
 import Protolude
-import qualified System.Posix.Signals as PS
+import System.Posix.Signals qualified as PS
 import System.Process
 
 performEffect :: EffectTask.EffectTask -> App TaskStatus
diff --git a/hercules-ci-agent/Hercules/Agent/Env.hs b/hercules-ci-agent/Hercules/Agent/Env.hs
--- a/hercules-ci-agent/Hercules/Agent/Env.hs
+++ b/hercules-ci-agent/Hercules/Agent/Env.hs
@@ -7,27 +7,27 @@
 import Control.Monad.Catch
 import Control.Monad.IO.Unlift
 import Control.Monad.Trans.Control (MonadBaseControl)
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Hercules.API.Agent.Socket.AgentPayload (AgentPayload)
 import Hercules.API.Agent.Socket.ServicePayload (ServicePayload)
-import qualified Hercules.Agent.Cachix.Env as Cachix
+import Hercules.Agent.Cachix.Env qualified as Cachix
   ( Env,
     HasEnv (..),
   )
 import Hercules.Agent.Config (FinalConfig)
-import qualified Hercules.Agent.Config.BinaryCaches as Config.BinaryCaches
-import qualified Hercules.Agent.Netrc.Env as Netrc
-import qualified Hercules.Agent.Nix.Env as Nix
+import Hercules.Agent.Config.BinaryCaches qualified as Config.BinaryCaches
+import Hercules.Agent.Netrc.Env qualified as Netrc
+import Hercules.Agent.Nix.Env qualified as Nix
   ( Env,
   )
-import qualified Hercules.Agent.ServiceInfo as ServiceInfo
+import Hercules.Agent.ServiceInfo qualified as ServiceInfo
 import Hercules.Agent.Socket (Socket)
 import Hercules.Error
-import qualified Katip as K
-import qualified Network.HTTP.Client
+import Katip qualified as K
+import Network.HTTP.Client qualified
 import Protolude
-import qualified Servant.Auth.Client
-import qualified Servant.Client.Streaming
+import Servant.Auth.Client qualified
+import Servant.Client.Streaming qualified
 
 data Env = Env
   { manager :: Network.HTTP.Client.Manager,
@@ -66,7 +66,7 @@
   getEnv = cachixEnv
 
 newtype App a = App {fromApp :: ReaderT Env IO a}
-  deriving (Functor, Applicative, Monad, MonadReader Env, MonadIO, MonadCatch, MonadMask, MonadThrow, MonadUnliftIO, MonadBase IO, MonadBaseControl IO)
+  deriving newtype (Functor, Applicative, Monad, MonadReader Env, MonadIO, MonadCatch, MonadMask, MonadThrow, MonadUnliftIO, MonadBase IO, MonadBaseControl IO)
 
 runApp :: Env -> App a -> IO a
 runApp env (App m) = runReaderT m env
diff --git a/hercules-ci-agent/Hercules/Agent/EnvironmentInfo.hs b/hercules-ci-agent/Hercules/Agent/EnvironmentInfo.hs
--- a/hercules-ci-agent/Hercules/Agent/EnvironmentInfo.hs
+++ b/hercules-ci-agent/Hercules/Agent/EnvironmentInfo.hs
@@ -2,18 +2,18 @@
 
 module Hercules.Agent.EnvironmentInfo where
 
-import qualified Data.ByteString as BS
-import qualified Data.Set as S
-import qualified Data.Text as T
-import qualified Hercules.API.Agent.LifeCycle.AgentInfo as AgentInfo
+import Data.ByteString qualified as BS
+import Data.Set qualified as S
+import Data.Text qualified as T
+import Hercules.API.Agent.LifeCycle.AgentInfo qualified as AgentInfo
 import Hercules.Agent.CabalInfo as CabalInfo
 import Hercules.Agent.Cachix.Info as Cachix.Info
-import qualified Hercules.Agent.Config as Config
+import Hercules.Agent.Config qualified as Config
 import Hercules.Agent.Env as Env
 import Hercules.Agent.Log
-import qualified Hercules.CNix as CNix
-import qualified Hercules.CNix.Settings as Settings
-import qualified Hercules.CNix.Store as Store
+import Hercules.CNix qualified as CNix
+import Hercules.CNix.Settings qualified as Settings
+import Hercules.CNix.Store qualified as Store
 import Network.HostName (getHostName)
 import Protolude hiding (to)
 
diff --git a/hercules-ci-agent/Hercules/Agent/Evaluate.hs b/hercules-ci-agent/Hercules/Agent/Evaluate.hs
--- a/hercules-ci-agent/Hercules/Agent/Evaluate.hs
+++ b/hercules-ci-agent/Hercules/Agent/Evaluate.hs
@@ -8,15 +8,15 @@
 where
 
 import Conduit
-import qualified Control.Concurrent.Async.Lifted as Async.Lifted
+import Control.Concurrent.Async.Lifted qualified as Async.Lifted
 import Control.Concurrent.Chan.Lifted
 import Control.Exception.Lifted (finally)
-import qualified Control.Exception.Safe as Safe
+import Control.Exception.Safe qualified as Safe
 import Control.Lens (at, (^?))
 import Control.Monad.IO.Unlift (askUnliftIO, unliftIO)
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.Aeson.Lens (_String)
-import qualified Data.ByteString.Lazy as BL
+import Data.ByteString.Lazy qualified as BL
 import Data.Char (isAsciiLower, isAsciiUpper)
 import Data.Conduit.Process (sourceProcessWithStreams)
 import Data.IORef
@@ -24,77 +24,77 @@
     newIORef,
     readIORef,
   )
-import qualified Data.Map as M
-import qualified Data.Set as S
-import qualified Data.Text as T
+import Data.Map qualified as M
+import Data.Set qualified as S
+import Data.Text qualified as T
 import Data.UUID (UUID)
 import Hercules.API (Id)
 import Hercules.API.Agent.Evaluate
   ( getDerivationStatus2,
     tasksUpdateEvaluation,
   )
-import qualified Hercules.API.Agent.Evaluate.DerivationStatus as DerivationStatus
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent as EvaluateEvent
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEffectEvent as AttributeEffectEvent
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeErrorEvent as AttributeErrorEvent
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEvent as AttributeEvent
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeIFDEvent as AttributeIFDEvent
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.BuildRequest as BuildRequest
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.BuildRequired as BuildRequired
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.DerivationInfo as DerivationInfo
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.JobConfig as JobConfig
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.Message as Message
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.PushedAll as PushedAll
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask as EvaluateTask
+import Hercules.API.Agent.Evaluate.DerivationStatus qualified as DerivationStatus
+import Hercules.API.Agent.Evaluate.EvaluateEvent qualified as EvaluateEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEffectEvent qualified as AttributeEffectEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeErrorEvent qualified as AttributeErrorEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEvent qualified as AttributeEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeIFDEvent qualified as AttributeIFDEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.BuildRequest qualified as BuildRequest
+import Hercules.API.Agent.Evaluate.EvaluateEvent.BuildRequired qualified as BuildRequired
+import Hercules.API.Agent.Evaluate.EvaluateEvent.DerivationInfo qualified as DerivationInfo
+import Hercules.API.Agent.Evaluate.EvaluateEvent.JobConfig qualified as JobConfig
+import Hercules.API.Agent.Evaluate.EvaluateEvent.Message qualified as Message
+import Hercules.API.Agent.Evaluate.EvaluateEvent.PushedAll qualified as PushedAll
+import Hercules.API.Agent.Evaluate.EvaluateTask qualified as EvaluateTask
 import Hercules.API.Agent.Evaluate.ImmutableGitInput (ImmutableGitInput)
-import qualified Hercules.API.Agent.Evaluate.ImmutableGitInput as ImmutableGitInput
-import qualified Hercules.API.Agent.Evaluate.ImmutableInput as ImmutableInput
+import Hercules.API.Agent.Evaluate.ImmutableGitInput qualified as ImmutableGitInput
+import Hercules.API.Agent.Evaluate.ImmutableInput qualified as ImmutableInput
 import Hercules.API.Servant (noContent)
 import Hercules.API.Task (Task)
-import qualified Hercules.Agent.Cache as Agent.Cache
-import qualified Hercules.Agent.Client
-import qualified Hercules.Agent.Config as Config
+import Hercules.Agent.Cache qualified as Agent.Cache
+import Hercules.Agent.Client qualified
+import Hercules.Agent.Config qualified as Config
 import Hercules.Agent.Env
-import qualified Hercules.Agent.Env as Env
+import Hercules.Agent.Env qualified as Env
 import Hercules.Agent.Evaluate.TraversalQueue (Queue)
-import qualified Hercules.Agent.Evaluate.TraversalQueue as TraversalQueue
+import Hercules.Agent.Evaluate.TraversalQueue qualified as TraversalQueue
 import Hercules.Agent.Files
 import Hercules.Agent.Log
-import qualified Hercules.Agent.Netrc as Netrc
-import qualified Hercules.Agent.Nix as Nix
+import Hercules.Agent.Netrc qualified as Netrc
+import Hercules.Agent.Nix qualified as Nix
 import Hercules.Agent.Nix.RetrieveDerivationInfo
   ( retrieveDerivationInfo,
   )
 import Hercules.Agent.NixFile (findNixFile)
-import qualified Hercules.Agent.NixFile.GitSource as GitSource
+import Hercules.Agent.NixFile.GitSource qualified as GitSource
 import Hercules.Agent.NixPath
   ( renderSubPath,
   )
 import Hercules.Agent.Producer
 import Hercules.Agent.Sensitive (Sensitive (Sensitive))
-import qualified Hercules.Agent.ServiceInfo as ServiceInfo
+import Hercules.Agent.ServiceInfo qualified as ServiceInfo
 import Hercules.Agent.WorkerProcess ()
-import qualified Hercules.Agent.WorkerProcess as WorkerProcess
-import qualified Hercules.Agent.WorkerProtocol.Command as Command
-import qualified Hercules.Agent.WorkerProtocol.Command.BuildResult as BuildResult
-import qualified Hercules.Agent.WorkerProtocol.Command.Eval as Eval
-import qualified Hercules.Agent.WorkerProtocol.Event as Event
-import qualified Hercules.Agent.WorkerProtocol.Event.Attribute as WorkerAttribute
-import qualified Hercules.Agent.WorkerProtocol.Event.AttributeError as WorkerAttributeError
-import qualified Hercules.Agent.WorkerProtocol.Event.AttributeIFD as AttributeIFD
-import qualified Hercules.Agent.WorkerProtocol.LogSettings as LogSettings
+import Hercules.Agent.WorkerProcess qualified as WorkerProcess
+import Hercules.Agent.WorkerProtocol.Command qualified as Command
+import Hercules.Agent.WorkerProtocol.Command.BuildResult qualified as BuildResult
+import Hercules.Agent.WorkerProtocol.Command.Eval qualified as Eval
+import Hercules.Agent.WorkerProtocol.Event qualified as Event
+import Hercules.Agent.WorkerProtocol.Event.Attribute qualified as WorkerAttribute
+import Hercules.Agent.WorkerProtocol.Event.AttributeError qualified as WorkerAttributeError
+import Hercules.Agent.WorkerProtocol.Event.AttributeIFD qualified as AttributeIFD
+import Hercules.Agent.WorkerProtocol.LogSettings qualified as LogSettings
 import Hercules.Agent.WorkerProtocol.ViaJSON (ViaJSON (ViaJSON), fromViaJSON)
 import Hercules.CNix.Store (Store, StorePath, parseStorePath)
-import qualified Hercules.CNix.Store as CNix
+import Hercules.CNix.Store qualified as CNix
 import Hercules.Effect (parseDrvSecretsMap)
 import Hercules.Error (defaultRetry, quickRetry)
-import qualified Network.HTTP.Client.Conduit as HTTP.Conduit
-import qualified Network.HTTP.Simple as HTTP.Simple
-import qualified Network.URI
+import Network.HTTP.Client.Conduit qualified as HTTP.Conduit
+import Network.HTTP.Simple qualified as HTTP.Simple
+import Network.URI qualified
 import Protolude hiding (finally, newChan, writeChan)
-import qualified Servant.Client
+import Servant.Client qualified
 import Servant.Client.Core (showBaseUrl)
-import qualified System.Directory as Dir
+import System.Directory qualified as Dir
 import System.FilePath
 import System.Process
 import UnliftIO (atomicModifyIORef')
@@ -219,7 +219,7 @@
           paths <- liftIO $ readIORef topDerivationPaths
           forM_ caches $ \cache -> do
             withNamedContext "cache" cache $ logLocM DebugS "Pushing derivations"
-            Agent.Cache.push cache (toList paths) pushEvalWorkers
+            Agent.Cache.push store cache (toList paths) pushEvalWorkers
             emit $ EvaluateEvent.PushedAll $ PushedAll.PushedAll {cache = cache}
         captureAttrDrvAndEmit msg = do
           case msg of
@@ -363,7 +363,7 @@
             paths <- liftIO $ readIORef topDerivationPaths
             forM_ caches $ \cache -> do
               withNamedContext "cache" cache $ logLocM DebugS "Pushing derivations"
-              Agent.Cache.push cache (toList paths) pushEvalWorkers
+              Agent.Cache.push store cache (toList paths) pushEvalWorkers
               emit $ EvaluateEvent.PushedAll $ PushedAll.PushedAll {cache = cache}
           captureAttrDrvAndEmit msg = do
             case msg of
@@ -622,7 +622,7 @@
                         caches <- activePushCaches
                         forM_ caches $ \cache -> do
                           withNamedContext "cache" cache $ logLocM DebugS "Pushing derivations for import from derivation"
-                          Agent.Cache.push cache [storePath] pushEvalWorkers
+                          Agent.Cache.push store cache [storePath] pushEvalWorkers
                   Async.Lifted.concurrently_
                     (uploadDerivationInfos storePath)
                     pushDerivations
@@ -732,7 +732,8 @@
     Just (attempt, DerivationStatus.BuildSuccess) -> pure (attempt, BuildResult.Success)
 
 newtype SubprocessFailure = SubprocessFailure {message :: Text}
-  deriving (Typeable, Exception, Show)
+  deriving (Typeable, Show)
+  deriving anyclass (Exception)
 
 fetchSource :: FilePath -> Text -> App FilePath
 fetchSource targetDir url = do
diff --git a/hercules-ci-agent/Hercules/Agent/Evaluate/TraversalQueue.hs b/hercules-ci-agent/Hercules/Agent/Evaluate/TraversalQueue.hs
--- a/hercules-ci-agent/Hercules/Agent/Evaluate/TraversalQueue.hs
+++ b/hercules-ci-agent/Hercules/Agent/Evaluate/TraversalQueue.hs
@@ -19,7 +19,7 @@
 import Control.Monad.Base
 import Control.Monad.Trans.Control
 import Data.IORef.Lifted
-import qualified Data.Set as Set
+import Data.Set qualified as Set
 import Protolude hiding
   ( bracket,
     newChan,
@@ -59,7 +59,7 @@
     check (n == 0)
 
 readJust_ ::
-  (MonadBase IO m, MonadIO m) =>
+  (MonadBase IO m) =>
   Chan (Maybe a) ->
   (a -> m ()) ->
   m ()
diff --git a/hercules-ci-agent/Hercules/Agent/Files.hs b/hercules-ci-agent/Hercules/Agent/Files.hs
--- a/hercules-ci-agent/Hercules/Agent/Files.hs
+++ b/hercules-ci-agent/Hercules/Agent/Files.hs
@@ -3,7 +3,7 @@
 module Hercules.Agent.Files where
 
 import Control.Monad.IO.Unlift
-import qualified Hercules.Agent.Config as Config
+import Hercules.Agent.Config qualified as Config
 import Hercules.Agent.Env
 import Protolude
 import System.Directory
diff --git a/hercules-ci-agent/Hercules/Agent/Init.hs b/hercules-ci-agent/Hercules/Agent/Init.hs
--- a/hercules-ci-agent/Hercules/Agent/Init.hs
+++ b/hercules-ci-agent/Hercules/Agent/Init.hs
@@ -1,28 +1,30 @@
+{-# LANGUAGE BlockArguments #-}
+
 module Hercules.Agent.Init where
 
-import qualified Hercules.Agent.Cachix.Init
-import qualified Hercules.Agent.Compat as Compat
-import qualified Hercules.Agent.Config as Config
-import qualified Hercules.Agent.Config.BinaryCaches as BC
+import Hercules.Agent.Cachix.Init qualified
+import Hercules.Agent.Compat qualified as Compat
+import Hercules.Agent.Config qualified as Config
+import Hercules.Agent.Config.BinaryCaches qualified as BC
 import Hercules.Agent.Env (Env (Env))
-import qualified Hercules.Agent.Env as Env
-import qualified Hercules.Agent.Netrc.Env as Netrc
-import qualified Hercules.Agent.Nix.Init
-import qualified Hercules.Agent.SecureDirectory as SecureDirectory
-import qualified Hercules.Agent.ServiceInfo as ServiceInfo
-import qualified Hercules.Agent.Token as Token
-import qualified Hercules.CNix
-import qualified Hercules.CNix.Util
-import qualified Hercules.CNix.Verbosity
-import qualified Katip as K
-import qualified Network.HTTP.Client.TLS
+import Hercules.Agent.Env qualified as Env
+import Hercules.Agent.Netrc.Env qualified as Netrc
+import Hercules.Agent.Nix.Init qualified
+import Hercules.Agent.SecureDirectory qualified as SecureDirectory
+import Hercules.Agent.ServiceInfo qualified as ServiceInfo
+import Hercules.Agent.Token qualified as Token
+import Hercules.CNix qualified
+import Hercules.CNix.Util qualified
+import Hercules.CNix.Verbosity qualified
+import Katip qualified as K
+import Network.HTTP.Client.TLS qualified
 import Protolude
-import qualified Servant.Auth.Client
-import qualified Servant.Client
-import qualified System.Directory
+import Servant.Auth.Client qualified
+import Servant.Client qualified
+import System.Directory qualified
 
-newEnv :: Config.FinalConfig -> K.LogEnv -> IO Env
-newEnv config logEnv = do
+withEnv :: Config.FinalConfig -> K.LogEnv -> (Env -> IO a) -> IO a
+withEnv config logEnv f = do
   let withLogging :: K.KatipContextT IO a -> IO a
       withLogging = K.runKatipContextT logEnv () "Init"
   withLogging $ K.logLocM K.DebugS $ "Config: " <> K.logStr (show config :: Text)
@@ -34,26 +36,27 @@
   let clientEnv :: Servant.Client.ClientEnv
       clientEnv = Servant.Client.mkClientEnv manager baseUrl
   token <- Token.readTokenFile $ toS $ Config.clusterJoinTokenPath config
-  cachix <- withLogging $ Hercules.Agent.Cachix.Init.newEnv config (BC.cachixCaches bcs)
-  nix <- Hercules.Agent.Nix.Init.newEnv
-  serviceInfo <- ServiceInfo.newEnv clientEnv
-  pure
-    Env
-      { manager = manager,
-        config = config,
-        herculesBaseUrl = baseUrl,
-        herculesClientEnv = clientEnv,
-        serviceInfo = serviceInfo,
-        currentToken = Servant.Auth.Client.Token $ encodeUtf8 token,
-        binaryCaches = bcs,
-        cachixEnv = cachix,
-        socket = panic "Socket not defined yet.", -- Hmm, needs different monad?
-        kNamespace = emptyNamespace,
-        kContext = mempty,
-        kLogEnv = logEnv,
-        nixEnv = nix,
-        netrcEnv = Netrc.Env Nothing
-      }
+  withLogging $ Hercules.Agent.Cachix.Init.withEnv config (BC.cachixCaches bcs) \cachix -> liftIO do
+    nix <- Hercules.Agent.Nix.Init.newEnv
+    serviceInfo <- ServiceInfo.newEnv clientEnv
+    let env =
+          Env
+            { manager = manager,
+              config = config,
+              herculesBaseUrl = baseUrl,
+              herculesClientEnv = clientEnv,
+              serviceInfo = serviceInfo,
+              currentToken = Servant.Auth.Client.Token $ encodeUtf8 token,
+              binaryCaches = bcs,
+              cachixEnv = cachix,
+              socket = panic "Socket not defined yet.", -- Hmm, needs different monad?
+              kNamespace = emptyNamespace,
+              kContext = mempty,
+              kLogEnv = logEnv,
+              nixEnv = nix,
+              netrcEnv = Netrc.Env Nothing
+            }
+    f env
 
 setupLogging :: Config.FinalConfig -> (K.LogEnv -> IO ()) -> IO ()
 setupLogging cfg f = do
diff --git a/hercules-ci-agent/Hercules/Agent/Log.hs b/hercules-ci-agent/Hercules/Agent/Log.hs
--- a/hercules-ci-agent/Hercules/Agent/Log.hs
+++ b/hercules-ci-agent/Hercules/Agent/Log.hs
@@ -10,10 +10,10 @@
 where
 
 import Data.Aeson
-import qualified Data.Aeson as A
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.Map as M
+import Data.Aeson qualified as A
+import Data.ByteString qualified as BS
+import Data.ByteString.Lazy qualified as LBS
+import Data.Map qualified as M
 import Katip hiding (logLocM)
 import Katip.Core
 import Katip.Monadic (logLocM)
diff --git a/hercules-ci-agent/Hercules/Agent/Netrc.hs b/hercules-ci-agent/Hercules/Agent/Netrc.hs
--- a/hercules-ci-agent/Hercules/Agent/Netrc.hs
+++ b/hercules-ci-agent/Hercules/Agent/Netrc.hs
@@ -2,12 +2,12 @@
 
 module Hercules.Agent.Netrc where
 
-import qualified Data.Text as T
-import qualified Data.Text.IO as T
-import qualified Hercules.Agent.Env as Env
+import Data.Text qualified as T
+import Data.Text.IO qualified as T
+import Hercules.Agent.Env qualified as Env
 import Hercules.Agent.Netrc.Env (Env (Env, netrcFile))
-import qualified Hercules.Agent.Nix as Nix
-import qualified Hercules.Agent.SecureDirectory as SecureDirectory
+import Hercules.Agent.Nix qualified as Nix
+import Hercules.Agent.SecureDirectory qualified as SecureDirectory
 import Protolude
 import System.IO (hClose)
 
diff --git a/hercules-ci-agent/Hercules/Agent/Nix.hs b/hercules-ci-agent/Hercules/Agent/Nix.hs
--- a/hercules-ci-agent/Hercules/Agent/Nix.hs
+++ b/hercules-ci-agent/Hercules/Agent/Nix.hs
@@ -1,8 +1,8 @@
 module Hercules.Agent.Nix where
 
 import Control.Monad.Trans.Maybe
-import qualified Data.ByteString as BS
-import qualified Data.Text as T
+import Data.ByteString qualified as BS
+import Data.Text qualified as T
 import Hercules.Agent.Env as Agent.Env
 import Hercules.Agent.EnvironmentInfo (getNixInfo, nixNetrcFile)
 import Hercules.Agent.Nix.Env as Nix.Env
diff --git a/hercules-ci-agent/Hercules/Agent/Nix/Init.hs b/hercules-ci-agent/Hercules/Agent/Nix/Init.hs
--- a/hercules-ci-agent/Hercules/Agent/Nix/Init.hs
+++ b/hercules-ci-agent/Hercules/Agent/Nix/Init.hs
@@ -1,6 +1,6 @@
 module Hercules.Agent.Nix.Init where
 
-import qualified Hercules.Agent.EnvironmentInfo as EnvironmentInfo
+import Hercules.Agent.EnvironmentInfo qualified as EnvironmentInfo
 import Hercules.Agent.Nix.Env
 import Protolude
 
diff --git a/hercules-ci-agent/Hercules/Agent/Nix/RetrieveDerivationInfo.hs b/hercules-ci-agent/Hercules/Agent/Nix/RetrieveDerivationInfo.hs
--- a/hercules-ci-agent/Hercules/Agent/Nix/RetrieveDerivationInfo.hs
+++ b/hercules-ci-agent/Hercules/Agent/Nix/RetrieveDerivationInfo.hs
@@ -2,12 +2,12 @@
 
 module Hercules.Agent.Nix.RetrieveDerivationInfo where
 
-import qualified Data.Map as M
-import qualified Data.Text as T
+import Data.Map qualified as M
+import Data.Text qualified as T
 import Hercules.API.Agent.Evaluate.EvaluateEvent.DerivationInfo
   ( DerivationInfo (DerivationInfo),
   )
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.DerivationInfo as DerivationInfo
+import Hercules.API.Agent.Evaluate.EvaluateEvent.DerivationInfo qualified as DerivationInfo
 import Hercules.CNix
 import Protolude
 
diff --git a/hercules-ci-agent/Hercules/Agent/SecureDirectory.hs b/hercules-ci-agent/Hercules/Agent/SecureDirectory.hs
--- a/hercules-ci-agent/Hercules/Agent/SecureDirectory.hs
+++ b/hercules-ci-agent/Hercules/Agent/SecureDirectory.hs
@@ -3,10 +3,10 @@
 import Hercules.Agent.Config (FinalConfig, workDirectory)
 import Hercules.Agent.Env
 import Protolude
-import qualified System.Directory
+import System.Directory qualified
 import System.FilePath ((</>))
-import qualified System.IO.Temp
-import qualified System.Posix.Files as Posix
+import System.IO.Temp qualified
+import System.Posix.Files qualified as Posix
 
 init :: FinalConfig -> IO ()
 init cfg = do
diff --git a/hercules-ci-agent/Hercules/Agent/ServiceInfo.hs b/hercules-ci-agent/Hercules/Agent/ServiceInfo.hs
--- a/hercules-ci-agent/Hercules/Agent/ServiceInfo.hs
+++ b/hercules-ci-agent/Hercules/Agent/ServiceInfo.hs
@@ -1,12 +1,12 @@
 module Hercules.Agent.ServiceInfo where
 
-import qualified Hercules.API.Agent.LifeCycle as API.LifeCycle
-import qualified Hercules.API.Agent.LifeCycle.ServiceInfo as ServiceInfo
-import qualified Hercules.Agent.Client as Client
+import Hercules.API.Agent.LifeCycle qualified as API.LifeCycle
+import Hercules.API.Agent.LifeCycle.ServiceInfo qualified as ServiceInfo
+import Hercules.Agent.Client qualified as Client
 import Hercules.Error (escalate)
 import Network.URI
 import Protolude
-import qualified Servant.Client.Streaming
+import Servant.Client.Streaming qualified
 
 data Env = Env
   { agentSocketBaseURL :: URI,
diff --git a/hercules-ci-agent/Hercules/Agent/Token.hs b/hercules-ci-agent/Hercules/Agent/Token.hs
--- a/hercules-ci-agent/Hercules/Agent/Token.hs
+++ b/hercules-ci-agent/Hercules/Agent/Token.hs
@@ -1,22 +1,22 @@
 module Hercules.Agent.Token where
 
 import Control.Lens ((^?))
-import qualified Data.Aeson as Aeson
+import Data.Aeson qualified as Aeson
 import Data.Aeson.Lens (key, _String)
-import qualified Data.ByteString.Base64.Lazy as B64L
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.Text as T
-import qualified Hercules.API.Agent.LifeCycle
-import qualified Hercules.API.Agent.LifeCycle.CreateAgentSession_V2 as CreateAgentSession
+import Data.ByteString.Base64.Lazy qualified as B64L
+import Data.ByteString.Lazy qualified as BL
+import Data.Text qualified as T
+import Hercules.API.Agent.LifeCycle qualified
+import Hercules.API.Agent.LifeCycle.CreateAgentSession_V2 qualified as CreateAgentSession
 import Hercules.Agent.Client (lifeCycleClient)
 import Hercules.Agent.Config (baseDirectory)
 import Hercules.Agent.Env as Env
-import qualified Hercules.Agent.EnvironmentInfo as EnvironmentInfo
+import Hercules.Agent.EnvironmentInfo qualified as EnvironmentInfo
 import Hercules.Agent.Log
 import Hercules.Error
 import Protolude
 import Servant.Auth.Client (Token (Token))
-import qualified System.Directory
+import System.Directory qualified
 import System.FilePath ((</>))
 
 getDir :: App FilePath
diff --git a/hercules-ci-agent/Main.hs b/hercules-ci-agent/Main.hs
--- a/hercules-ci-agent/Main.hs
+++ b/hercules-ci-agent/Main.hs
@@ -3,7 +3,7 @@
   )
 where
 
-import qualified Hercules.Agent
+import Hercules.Agent qualified
 import Protolude
 import System.Posix.Signals
 
diff --git a/hercules-ci-nix-daemon/daemon.cc b/hercules-ci-nix-daemon/daemon.cc
--- a/hercules-ci-nix-daemon/daemon.cc
+++ b/hercules-ci-nix-daemon/daemon.cc
@@ -15,6 +15,11 @@
 
 using namespace nix;
 
+#if ! NIX_IS_AT_LEAST(2,15,0)
+using nix::daemon::TrustedFlag;
+using nix::daemon::NotTrusted;
+#endif
+
 static void sigChldHandler(int sigNo)
 {
     // Ensure we don't modify errno of whatever we've interrupted
@@ -88,7 +93,7 @@
                 FdSink to(remote.get());
                 // TODO: disable caching without interfering with user parameters
                 ref<Store> store = openStore();
-                daemon::TrustedFlag trusted = daemon::NotTrusted;
+                TrustedFlag trusted = NotTrusted;
                 daemon::RecursiveFlag recursive = daemon::NotRecursive;
 #if ! NIX_IS_AT_LEAST(2,14,0)
                 std::function<void(Store &)> authHook = [](Store &){};
diff --git a/src/Hercules/Agent/Binary.hs b/src/Hercules/Agent/Binary.hs
--- a/src/Hercules/Agent/Binary.hs
+++ b/src/Hercules/Agent/Binary.hs
@@ -2,8 +2,8 @@
 
 import Data.Binary
 import Data.Binary.Get
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Builder.Extra as BL
+import Data.ByteString qualified as BS
+import Data.ByteString.Builder.Extra qualified as BL
 import System.IO (Handle)
 import Prelude
 
diff --git a/src/Hercules/Agent/NixFile.hs b/src/Hercules/Agent/NixFile.hs
--- a/src/Hercules/Agent/NixFile.hs
+++ b/src/Hercules/Agent/NixFile.hs
@@ -32,14 +32,14 @@
 where
 
 import Control.Monad.Trans.Maybe (MaybeT (MaybeT), runMaybeT)
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Hercules.API.Agent.Evaluate.EvaluateEvent.InputDeclaration (InputDeclaration (SiblingInput), SiblingInput (MkSiblingInput))
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.InputDeclaration
+import Hercules.API.Agent.Evaluate.EvaluateEvent.InputDeclaration qualified
 import Hercules.Agent.NixFile.CiNixArgs (CiNixArgs (CiNixArgs))
-import qualified Hercules.Agent.NixFile.CiNixArgs
+import Hercules.Agent.NixFile.CiNixArgs qualified
 import Hercules.Agent.NixFile.GitSource (GitSource)
 import Hercules.Agent.NixFile.HerculesCIArgs (HerculesCIArgs)
-import qualified Hercules.Agent.NixFile.HerculesCIArgs as HerculesCIArgs
+import Hercules.Agent.NixFile.HerculesCIArgs qualified as HerculesCIArgs
 import Hercules.CNix.Expr
   ( EvalState,
     Match (IsAttrs),
@@ -59,11 +59,11 @@
   )
 import Hercules.CNix.Expr.Raw (RawValue)
 import Hercules.CNix.Expr.Schema (Attrs, Dictionary, MonadEval, PSObject (PSObject), Provenance (Other), StringWithoutContext, basicAttrsWithProvenance, dictionaryToMap, fromPSObject, toPSObject, (#.), (#?), ($?), (.$), (>>$.), type (->.), type (->?), type (.), type (::.), type (::?), type (::??), type (?), type (|.))
-import qualified Hercules.CNix.Expr.Schema as Schema
+import Hercules.CNix.Expr.Schema qualified as Schema
 import Hercules.Error (escalateAs)
 import Paths_hercules_ci_agent (getDataFileName)
 import Protolude hiding (evalState)
-import qualified System.Directory as Dir
+import System.Directory qualified as Dir
 import System.FilePath (takeDirectory, takeFileName, (</>))
 import UnliftIO.Directory (doesPathExist)
 
diff --git a/src/Hercules/Agent/NixFile/GitSource.hs b/src/Hercules/Agent/NixFile/GitSource.hs
--- a/src/Hercules/Agent/NixFile/GitSource.hs
+++ b/src/Hercules/Agent/NixFile/GitSource.hs
@@ -4,7 +4,7 @@
 module Hercules.Agent.NixFile.GitSource where
 
 import Data.Aeson (FromJSON, ToJSON)
-import qualified Data.Text as T
+import Data.Text qualified as T
 import Hercules.CNix.Expr (ToRawValue, ViaJSON (ViaJSON))
 import Protolude
 
diff --git a/src/Hercules/Agent/NixFile/HerculesCIArgs.hs b/src/Hercules/Agent/NixFile/HerculesCIArgs.hs
--- a/src/Hercules/Agent/NixFile/HerculesCIArgs.hs
+++ b/src/Hercules/Agent/NixFile/HerculesCIArgs.hs
@@ -5,7 +5,7 @@
 
 import Data.Aeson (ToJSON)
 import Hercules.Agent.NixFile.GitSource (GitSource)
-import qualified Hercules.Agent.NixFile.GitSource as GitSource
+import Hercules.Agent.NixFile.GitSource qualified as GitSource
 import Hercules.CNix.Expr (ToRawValue, ViaJSON (ViaJSON))
 import Protolude
 
@@ -30,7 +30,8 @@
   deriving (ToRawValue) via (ViaJSON HerculesCIArgs)
 
 newtype CISystems = CISystems (Maybe (Map Text ()))
-  deriving (Generic, ToJSON)
+  deriving (Generic)
+  deriving anyclass (ToJSON)
   deriving (ToRawValue) via (ViaJSON CISystems)
 
 fromGitSource :: GitSource -> HerculesCIMeta -> HerculesCIArgs
diff --git a/src/Hercules/Agent/NixPath.hs b/src/Hercules/Agent/NixPath.hs
--- a/src/Hercules/Agent/NixPath.hs
+++ b/src/Hercules/Agent/NixPath.hs
@@ -5,8 +5,8 @@
   )
 where
 
-import qualified Data.Text as T
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask as EvaluateTask
+import Data.Text qualified as T
+import Hercules.API.Agent.Evaluate.EvaluateTask qualified as EvaluateTask
 import Protolude
 
 renderNixPath ::
diff --git a/src/Hercules/Agent/Producer.hs b/src/Hercules/Agent/Producer.hs
--- a/src/Hercules/Agent/Producer.hs
+++ b/src/Hercules/Agent/Producer.hs
@@ -41,7 +41,7 @@
 -- receives a function for returning payloads @p@.
 --
 -- @f@ may produce a final result value @r@ when it is done.
-forkProducer :: forall m p r. (MonadIO m, MonadUnliftIO m) => ((p -> m ()) -> m r) -> m (Producer p r)
+forkProducer :: forall m p r. (MonadUnliftIO m) => ((p -> m ()) -> m r) -> m (Producer p r)
 forkProducer f = do
   q <- liftIO newTQueueIO
   let write :: MonadIO m' => Msg p r -> m' ()
@@ -89,7 +89,7 @@
 -- | Sends sync notifications after the whole computation succeeds (or fails)
 -- Note: not exception safe in the presence of pure exceptions.
 withSync ::
-  (MonadIO m, MonadUnliftIO m, Traversable t) =>
+  (MonadUnliftIO m, Traversable t) =>
   t (Syncing a) ->
   (t (Maybe a) -> m b) ->
   m b
@@ -121,7 +121,7 @@
 --     - Alternatively, maybe use stm-delay (which uses GHC.Event for efficiency)
 --       https://hackage.haskell.org/package/stm-delay-0.1.1.1/docs/Control-Concurrent-STM-Delay.html
 withBoundedDelayBatchProducer ::
-  (MonadIO m, MonadUnliftIO m) =>
+  (MonadUnliftIO m) =>
   -- | Max time before flushing in microseconds
   Int ->
   -- | Max number of items in batch
diff --git a/src/Hercules/Agent/STM.hs b/src/Hercules/Agent/STM.hs
--- a/src/Hercules/Agent/STM.hs
+++ b/src/Hercules/Agent/STM.hs
@@ -12,7 +12,7 @@
 where
 
 import Control.Concurrent.STM (STM, TBQueue, TChan, TVar, readTVar, writeTVar)
-import qualified Control.Concurrent.STM as STM
+import Control.Concurrent.STM qualified as STM
 import Protolude hiding (atomically)
 
 atomically :: MonadIO m => STM a -> m a
diff --git a/src/Hercules/Agent/Socket.hs b/src/Hercules/Agent/Socket.hs
--- a/src/Hercules/Agent/Socket.hs
+++ b/src/Hercules/Agent/Socket.hs
@@ -17,23 +17,23 @@
 import Control.Concurrent.STM.TChan (TChan, writeTChan)
 import Control.Concurrent.STM.TVar (TVar, modifyTVar, readTVar, writeTVar)
 import Control.Monad.IO.Unlift
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.DList (DList, fromList)
 import Data.List (dropWhileEnd, splitAt)
 import Data.Semigroup
 import Data.Time (NominalDiffTime, addUTCTime, diffUTCTime, getCurrentTime)
 import Data.Time.Extras
 import Hercules.API.Agent.LifeCycle.ServiceInfo (ServiceInfo)
-import qualified Hercules.API.Agent.LifeCycle.ServiceInfo as ServiceInfo
+import Hercules.API.Agent.LifeCycle.ServiceInfo qualified as ServiceInfo
 import Hercules.API.Agent.Socket.Frame (Frame)
-import qualified Hercules.API.Agent.Socket.Frame as Frame
+import Hercules.API.Agent.Socket.Frame qualified as Frame
 import Hercules.Agent.STM (atomically, newTChanIO, newTVarIO)
 import Katip (KatipContext, Severity (..), katipAddContext, katipAddNamespace, logLocM, sl)
 import Network.URI (URI, uriAuthority, uriPath, uriPort, uriQuery, uriRegName, uriScheme)
 import Network.WebSockets (Connection, runClientWith)
-import qualified Network.WebSockets as WS
+import Network.WebSockets qualified as WS
 import Protolude hiding (atomically, handle, race, race_)
-import qualified UnliftIO
+import UnliftIO qualified
 import UnliftIO.Async (race, race_)
 import UnliftIO.Exception (handle)
 import UnliftIO.STM (readTVarIO)
diff --git a/src/Hercules/Agent/WorkerProcess.hs b/src/Hercules/Agent/WorkerProcess.hs
--- a/src/Hercules/Agent/WorkerProcess.hs
+++ b/src/Hercules/Agent/WorkerProcess.hs
@@ -9,7 +9,7 @@
 where
 
 import Conduit hiding (Producer)
-import qualified Control.Exception.Safe as Safe
+import Control.Exception.Safe qualified as Safe
 import Control.Monad.IO.Unlift
 import Data.Binary (Binary)
 import Data.Conduit.Extras (conduitToCallbacks, sourceChan)
@@ -17,9 +17,9 @@
   ( conduitDecode,
     conduitEncode,
   )
-import qualified Data.Map as M
+import Data.Map qualified as M
 import GHC.IO.Exception
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask as EvaluateTask
+import Hercules.API.Agent.Evaluate.EvaluateTask qualified as EvaluateTask
 import Hercules.Agent.NixPath (renderNixPath)
 import Paths_hercules_ci_agent (getBinDir)
 import Protolude
diff --git a/src/Hercules/Agent/WorkerProtocol/Command.hs b/src/Hercules/Agent/WorkerProtocol/Command.hs
--- a/src/Hercules/Agent/WorkerProtocol/Command.hs
+++ b/src/Hercules/Agent/WorkerProtocol/Command.hs
@@ -3,12 +3,15 @@
 module Hercules.Agent.WorkerProtocol.Command where
 
 import Data.Binary
-import qualified Hercules.Agent.WorkerProtocol.Command.Build as Build
-import qualified Hercules.Agent.WorkerProtocol.Command.BuildResult as BuildResult
-import qualified Hercules.Agent.WorkerProtocol.Command.Effect as Effect
-import qualified Hercules.Agent.WorkerProtocol.Command.Eval as Eval
+import Hercules.Agent.WorkerProtocol.Command.Build qualified as Build
+import Hercules.Agent.WorkerProtocol.Command.BuildResult qualified as BuildResult
+import Hercules.Agent.WorkerProtocol.Command.Effect qualified as Effect
+import Hercules.Agent.WorkerProtocol.Command.Eval qualified as Eval
 import Protolude
 
+-- | Information flowing from the environment to the worker. The name isn't
+-- accurate as it includes other information than just commands,
+-- e.g. 'BuildResult'.
 data Command
   = Eval Eval.Eval
   | BuildResult BuildResult.BuildResult
diff --git a/src/Hercules/Agent/WorkerProtocol/Command/Effect.hs b/src/Hercules/Agent/WorkerProtocol/Command/Effect.hs
--- a/src/Hercules/Agent/WorkerProtocol/Command/Effect.hs
+++ b/src/Hercules/Agent/WorkerProtocol/Command/Effect.hs
@@ -3,7 +3,7 @@
 
 module Hercules.Agent.WorkerProtocol.Command.Effect where
 
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.Binary
 import Hercules.API.Id (Id)
 import Hercules.Agent.Sensitive
diff --git a/src/Hercules/Agent/WorkerProtocol/Command/Eval.hs b/src/Hercules/Agent/WorkerProtocol/Command/Eval.hs
--- a/src/Hercules/Agent/WorkerProtocol/Command/Eval.hs
+++ b/src/Hercules/Agent/WorkerProtocol/Command/Eval.hs
@@ -3,7 +3,7 @@
 module Hercules.Agent.WorkerProtocol.Command.Eval where
 
 import Data.Binary
-import qualified Hercules.API.Agent.Evaluate.EvaluateTask as EvaluateTask
+import Hercules.API.Agent.Evaluate.EvaluateTask qualified as EvaluateTask
 import Hercules.API.Agent.Evaluate.ImmutableGitInput (ImmutableGitInput)
 import Hercules.Agent.NixFile.GitSource (GitSource)
 import Hercules.Agent.WorkerProtocol.LogSettings
diff --git a/src/Hercules/Agent/WorkerProtocol/Orphans.hs b/src/Hercules/Agent/WorkerProtocol/Orphans.hs
--- a/src/Hercules/Agent/WorkerProtocol/Orphans.hs
+++ b/src/Hercules/Agent/WorkerProtocol/Orphans.hs
@@ -4,7 +4,7 @@
 module Hercules.Agent.WorkerProtocol.Orphans where
 
 import Control.Monad.Fail (fail)
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.Binary (Binary (get, put))
 import Hercules.API.Id (Id (..))
 import Hercules.CNix.Expr (ViaJSON (ViaJSON))
diff --git a/src/Hercules/Agent/WorkerProtocol/ViaJSON.hs b/src/Hercules/Agent/WorkerProtocol/ViaJSON.hs
--- a/src/Hercules/Agent/WorkerProtocol/ViaJSON.hs
+++ b/src/Hercules/Agent/WorkerProtocol/ViaJSON.hs
@@ -1,6 +1,6 @@
 module Hercules.Agent.WorkerProtocol.ViaJSON where
 
-import qualified Data.Aeson as A
+import Data.Aeson qualified as A
 import Data.Binary (Binary (..))
 import Prelude
 
diff --git a/src/Hercules/Effect.hs b/src/Hercules/Effect.hs
--- a/src/Hercules/Effect.hs
+++ b/src/Hercules/Effect.hs
@@ -5,22 +5,22 @@
 module Hercules.Effect where
 
 import Control.Monad.Catch (MonadThrow)
-import qualified Data.Aeson as A
-import qualified Data.Aeson.KeyMap as AK
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.Map as M
+import Data.Aeson qualified as A
+import Data.Aeson.KeyMap qualified as AK
+import Data.ByteString qualified as BS
+import Data.ByteString.Lazy qualified as BL
+import Data.Map qualified as M
 import Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEffectEvent (GitToken (..), SecretRef (GitToken, SimpleSecret), SimpleSecret (MkSimpleSecret))
-import qualified Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEffectEvent
+import Hercules.API.Agent.Evaluate.EvaluateEvent.AttributeEffectEvent qualified
 import Hercules.API.Id (Id, idText)
 import Hercules.Agent.Sensitive (Sensitive (Sensitive, reveal), revealContainer)
-import qualified Hercules.Agent.WorkerProcess as WorkerProcess
+import Hercules.Agent.WorkerProcess qualified as WorkerProcess
 import Hercules.CNix (Derivation)
 import Hercules.CNix.Store (getDerivationArguments, getDerivationBuilder, getDerivationEnv)
 import Hercules.Effect.Container (BindMount (BindMount))
-import qualified Hercules.Effect.Container as Container
+import Hercules.Effect.Container qualified as Container
 import Hercules.Error (escalateAs)
-import qualified Hercules.Formats.Secret as Formats.Secret
+import Hercules.Formats.Secret qualified as Formats.Secret
 import Hercules.Secrets (SecretContext, evalCondition, evalConditionTrace)
 import Katip (KatipContext, Severity (..), logLocM, logStr)
 import Network.Socket (Family (AF_UNIX), SockAddr (SockAddrUnix), SocketType (Stream), bind, listen, socket, withFdSocket)
@@ -29,7 +29,7 @@
 import System.Posix (dup, fdToHandle)
 import UnliftIO.Directory (createDirectory, createDirectoryIfMissing)
 import UnliftIO.Process (withCreateProcess)
-import qualified UnliftIO.Process as Process
+import UnliftIO.Process qualified as Process
 
 parseDrvSecretsMap :: Map ByteString ByteString -> Either Text (Map Text SecretRef)
 parseDrvSecretsMap drvEnv =
@@ -58,7 +58,7 @@
 
 -- | Write secrets to file based on secretsMap value
 writeSecrets ::
-  (MonadIO m, KatipContext m) =>
+  (KatipContext m) =>
   -- | Whether we're in a friendly context, such as the CLI.
   Bool ->
   Maybe SecretContext ->
diff --git a/src/Hercules/Effect/Container.hs b/src/Hercules/Effect/Container.hs
--- a/src/Hercules/Effect/Container.hs
+++ b/src/Hercules/Effect/Container.hs
@@ -7,10 +7,10 @@
 import Control.Lens
 import Data.Aeson (Value (String), eitherDecode, encode, object, toJSON)
 import Data.Aeson.Lens
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.Map as M
-import qualified Data.UUID.V4 as UUID
+import Data.ByteString qualified as BS
+import Data.ByteString.Lazy qualified as BL
+import Data.Map qualified as M
+import Data.UUID.V4 qualified as UUID
 import GHC.IO.Exception (IOErrorType (HardwareFault))
 import Protolude
 import System.Directory (createDirectory)
diff --git a/src/Hercules/Secrets.hs b/src/Hercules/Secrets.hs
--- a/src/Hercules/Secrets.hs
+++ b/src/Hercules/Secrets.hs
@@ -10,10 +10,10 @@
   )
 where
 
-import qualified Control.Monad.Writer
+import Control.Monad.Writer qualified
 import Data.Binary (Binary)
 import Data.Tagged
-import qualified Data.Text as T
+import Data.Text qualified as T
 import Hercules.Formats.Secret
 import Protolude
 
diff --git a/src/Hercules/UserException.hs b/src/Hercules/UserException.hs
--- a/src/Hercules/UserException.hs
+++ b/src/Hercules/UserException.hs
@@ -3,7 +3,7 @@
 import Control.Exception (Exception (displayException))
 import Data.Monoid ((<>))
 import Data.Text (Text)
-import qualified Data.Text as T
+import Data.Text qualified as T
 import Prelude (Show (..))
 
 -- | 'Exception' representation of errors that may be caused by user error.
diff --git a/test/Hercules/Agent/Nix/RetrieveDerivationInfoSpec.hs b/test/Hercules/Agent/Nix/RetrieveDerivationInfoSpec.hs
--- a/test/Hercules/Agent/Nix/RetrieveDerivationInfoSpec.hs
+++ b/test/Hercules/Agent/Nix/RetrieveDerivationInfoSpec.hs
@@ -3,8 +3,8 @@
 
 module Hercules.Agent.Nix.RetrieveDerivationInfoSpec where
 
-import qualified Data.ByteString as BS
-import qualified Data.Map as M
+import Data.ByteString qualified as BS
+import Data.Map qualified as M
 import Hercules.API.Agent.Evaluate.EvaluateEvent.DerivationInfo
 import Hercules.Agent.Nix.RetrieveDerivationInfo
 import Hercules.CNix
diff --git a/test/Hercules/Agent/WorkerProcessSpec.hs b/test/Hercules/Agent/WorkerProcessSpec.hs
--- a/test/Hercules/Agent/WorkerProcessSpec.hs
+++ b/test/Hercules/Agent/WorkerProcessSpec.hs
@@ -1,6 +1,6 @@
 module Hercules.Agent.WorkerProcessSpec (spec) where
 
-import qualified Data.Map as M
+import Data.Map qualified as M
 import Hercules.API.Agent.Evaluate.EvaluateTask
 import Hercules.Agent.WorkerProcess
 import Protolude
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,21 +1,1 @@
-module Spec
-  ( spec,
-  )
-where
-
-import qualified Hercules.Agent.Nix.RetrieveDerivationInfoSpec
-import qualified Hercules.Agent.NixPathSpec
-import qualified Hercules.Agent.Worker.ConduitSpec
-import qualified Hercules.Agent.Worker.STMSpec
-import qualified Hercules.Agent.WorkerProcessSpec
-import qualified Hercules.SecretsSpec
-import Test.Hspec
-
-spec :: Spec
-spec = do
-  describe "Hercules.Agent.NixPathSpec" Hercules.Agent.NixPathSpec.spec
-  describe "Hercules.Agent.WorkerProcessSpec" Hercules.Agent.WorkerProcessSpec.spec
-  describe "Hercules.Agent.Nix.RetrieveDerivationInfo" Hercules.Agent.Nix.RetrieveDerivationInfoSpec.spec
-  describe "Hercules.Secret" Hercules.SecretsSpec.spec
-  describe "Hercules.Agent.Worker.STMSpec" Hercules.Agent.Worker.STMSpec.spec
-  describe "Hercules.Agent.Worker.Conduit" Hercules.Agent.Worker.ConduitSpec.spec
+{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-}
diff --git a/test/TestMain.hs b/test/TestMain.hs
--- a/test/TestMain.hs
+++ b/test/TestMain.hs
@@ -2,7 +2,7 @@
 
 import Hercules.CNix (init)
 import Protolude
-import qualified Spec
+import Spec qualified
 import Test.Hspec.Runner
 
 main :: IO ()
