Move SSD truth write predicate to typed Kotlin

ober

691b5b84d904a81b8694229ff9b925b7a7e43416

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index a5477f7..3eecb5e 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -1538,7 +1538,8 @@
                 fileExists fileIsRegular destinationNewFileDelta
                 oldDestinationBytes urlEffectivePort
                 remoteBearerTokenPresent remoteBearerTokenValid
-                remotePinPresent remoteRelativePathSafe)
+                remotePinPresent remoteRelativePathSafe
+                shouldCompareMoreCompleteTruth)
         (type File)
         (type URL)
         (type Int32)
@@ -1600,7 +1601,10 @@
         (def (remoteRelativePathSafe (relative : String)) : Bool
           (and (not (string-blank? relative))
                (and (not (string-starts-with? relative "/"))
-                    (not (string-contains? relative "..")))))))
+                    (not (string-contains? relative "..")))))
+        (def (shouldCompareMoreCompleteTruth (replaceIfMoreComplete : Bool)
+                                             (destination : File)) : Bool
+          (and replaceIfMoreComplete (fileExists destination)))))
 
     (typed-kotlin-file "com/sfb/ssdreview/JsonGeometry.kt"
       (kotlin-imports (org json JSONArray))
@@ -8041,7 +8045,7 @@
        "        val key = validatedSourceKey(truthSourceKey(truth)) ?: return false"
        "        val dest = truthPath(key)"
        "        val text = truth.toString(2)"
-       "        val shouldWrite = if (replaceIfMoreComplete && dest.exists()) {"
+       "        val shouldWrite = if (shouldCompareMoreCompleteTruth(replaceIfMoreComplete, dest)) {"
        "            val local = jsonObjectFromText(readLocalText(dest))"
        "            truthGroupCount(truth) >= truthGroupCount(local) || shouldReplaceLocal(dest, text, modified)"
        "        } else {"