Move SSD truth object checks to typed Kotlin

ober

8975923ce3d611dc458ff23142f05aa3e8e0c50e

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index f8883f3..76bd39a 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -6789,7 +6789,7 @@
        "                }"
        ""
        "                val remoteMatches = 0"
-       "                val existingTruth = localTruth ?: truthStore.loadTruth(session)"
+       "                val existingTruth = if (truthPresent(localTruth)) localTruth else truthStore.loadTruth(session)"
        "                val existingTruthGroupCount = nullableTruthGroupCount(existingTruth)"
        "                var ocrGuesses = 0"
        "                var detectorNote = \"\""
@@ -6864,14 +6864,16 @@
        "        thread {"
        "            val matches = truthStore.pullRemoteTruth(session)"
        "            if (nonPositiveCount(matches)) return@thread"
-       "            val truth = truthStore.loadTruth(session) ?: return@thread"
+       "            val truth = truthStore.loadTruth(session)"
+       "            if (!truthPresent(truth)) return@thread"
+       "            val loadedTruth = truthJsonObjectOrEmpty(truth)"
        "            val merged = session.copy("
        "                cells = mutableListOf(),"
        "                groups = mutableListOf(),"
        "                suppressedGroups = mutableListOf(),"
        "                ocrWords = session.ocrWords.toMutableList()"
        "            )"
-       "            merged.ssdArea = truthSsdAreaRect(truth)"
+       "            merged.ssdArea = truthSsdAreaRect(loadedTruth)"
        "            truthStore.applyTruth(merged)"
        "            ssdSessionPruneGroupsOutsideSsdArea(merged)"
        "            runOnUiThread {"