diff --git a/src/middleware/orchestrator.cpp b/src/middleware/orchestrator.cpp
index f526ac7..8803c8d 100644
--- a/src/middleware/orchestrator.cpp
+++ b/src/middleware/orchestrator.cpp
@@ -71,6 +71,19 @@ Orchestrator::Orchestrator(QObject *parent)
   connect(&timer_, &QTimer::timeout, this, &Orchestrator::processPendingTasks);
 }
 
+Orchestrator::~Orchestrator() {
+  delete dal_;
+}
+
+ki::PgDal& Orchestrator::dal() {
+  if (!dal_) {
+    dal_ = new ki::PgDal();
+    const QByteArray dsn = qgetenv("PG_DSN");
+    if (!dsn.isEmpty()) dal_->connect(dsn.toStdString()); else dal_->connect("stub://memory");
+  }
+  return *dal_;
+}
+
 void Orchestrator::start(int intervalMs) {
   ensureResolvedDirs();
   continuityHandshakeOnce();
@@ -178,11 +191,7 @@ bool Orchestrator::saveSnapshot(const QString &nameSpace,
                                 const QJsonObject &content,
                                 const QStringList &tags)
 {
-  ki::PgDal dal;
-  const QByteArray dsn = qgetenv("PG_DSN");
-  if (!dsn.isEmpty()) dal.connect(dsn.toStdString()); else dal.connect("stub://memory");
-
-  auto nsRow = dal.ensureNamespace(nameSpace.toStdString());
+  auto nsRow = dal().ensureNamespace(nameSpace.toStdString());
   if (!nsRow) return false;
 
   ki::ItemRow row;
@@ -194,22 +203,18 @@ bool Orchestrator::saveSnapshot(const QString &nameSpace,
   row.metadata_json = "{}";
   row.created_at = std::chrono::system_clock::now();
 
-  const std::string id = dal.upsertItem(row);
+  const std::string id = dal().upsertItem(row);
   return !id.empty();
 }
 
 std::optional<QJsonObject> Orchestrator::loadSnapshot(const QString &nameSpace,
                                                       const QString &key)
 {
-  ki::PgDal dal;
-  const QByteArray dsn = qgetenv("PG_DSN");
-  if (!dsn.isEmpty()) dal.connect(dsn.toStdString()); else dal.connect("stub://memory");
-
-  auto nsRow = dal.findNamespace(nameSpace.toStdString());
+  auto nsRow = dal().findNamespace(nameSpace.toStdString());
   if (!nsRow) return std::nullopt;
 
   std::vector<std::string> tags; tags.emplace_back("snapshot");
-  auto rows = dal.fetchContext(nsRow->id, std::optional<std::string>(key.toStdString()), tags, std::nullopt, 1);
+  auto rows = dal().fetchContext(nsRow->id, std::optional<std::string>(key.toStdString()), tags, std::nullopt, 1);
   if (rows.empty()) return std::nullopt;
   const auto &row = rows.front();
   if (row.content_json.empty()) return std::nullopt;
diff --git a/src/middleware/orchestrator.h b/src/middleware/orchestrator.h
index 1da47ee..de889c1 100644
--- a/src/middleware/orchestrator.h
+++ b/src/middleware/orchestrator.h
@@ -8,6 +8,8 @@
 
 #include "kompanion_mw_export.h"
 
+namespace ki { class PgDal; }
+
 // Minimal model provider interface so tests can stub generation.
 class IModelProvider {
 public:
@@ -49,6 +51,7 @@ class KOMPANION_MW_EXPORT Orchestrator : public QObject {
   Q_OBJECT
 public:
   explicit Orchestrator(QObject *parent=nullptr);
+  ~Orchestrator();
 
   // Injectable model provider (Ollama by default). Ownership left to caller.
   void setModelProvider(IModelProvider *prov) { model_ = prov; }
@@ -104,4 +107,7 @@ private:
   QTimer timer_;
   bool continuityDone_ = false;
   IModelProvider *model_ = nullptr; // not owned
+  // Reused DB handle so in-memory stub persists across calls in tests.
+  ki::PgDal* dal_ = nullptr;
+  ki::PgDal& dal();
 };
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index cd17fe0..d0b1884 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -11,3 +11,9 @@ qt_add_executable(test_orchestrator
 )
 target_link_libraries(test_orchestrator PRIVATE Qt6::Core Qt6::Network Qt6::Test kompanion_mw)
 add_test(NAME test_orchestrator COMMAND test_orchestrator)
+
+qt_add_executable(test_snapshot
+  test_snapshot.cpp
+)
+target_link_libraries(test_snapshot PRIVATE Qt6::Core Qt6::Network Qt6::Test kompanion_mw)
+add_test(NAME test_snapshot COMMAND test_snapshot)
diff --git a/tests/test_snapshot.cpp b/tests/test_snapshot.cpp
new file mode 100644
index 0000000..354cf8e
--- /dev/null
+++ b/tests/test_snapshot.cpp
@@ -0,0 +1,25 @@
+#include <QtTest>
+#include "../src/middleware/orchestrator.h"
+
+class SnapshotTest : public QObject {
+  Q_OBJECT
+private slots:
+  void round_trip() {
+    // Ensure no PG_DSN is required; Orchestrator maintains a shared in-memory DAL per instance
+    Orchestrator orch;
+    const QString ns = QStringLiteral("tests");
+    const QString key = QStringLiteral("session:last");
+
+    QJsonObject payload{{"a", 1}, {"b", QStringLiteral("x")}};
+    QVERIFY2(orch.saveSnapshot(ns, key, payload), "saveSnapshot should succeed");
+
+    auto loaded = orch.loadSnapshot(ns, key);
+    QVERIFY2(loaded.has_value(), "loadSnapshot should return value");
+    QCOMPARE(loaded->value("a").toInt(), 1);
+    QCOMPARE(loaded->value("b").toString(), QStringLiteral("x"));
+  }
+};
+
+QTEST_MAIN(SnapshotTest)
+#include "test_snapshot.moc"
+
