Generate SSD truth snapshot saves from typed Jerboa

ober

b53e4b0263363ad763ded9865496b2d7e5ed85f3

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 1dbc6d4..632bca6 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -15564,6 +15564,7 @@
                 truthStoreAppendJsonLineLocal
                 truthStoreTruthTimeLocal
                 truthStoreShouldReplaceLocal
+                truthStoreSaveTruthSnapshotLocal
                 truthStoreMergeJsonLinesLocal)
         (type AssetManager)
         (type Any)
@@ -15629,6 +15630,10 @@
                   (store : TruthStore)
                   (truth : JSONObject)) : File
           (kotlin-member-call saveTruthSnapshot))
+        (extern (truthStorePushTruthAsyncRaw
+                  (store : TruthStore)
+                  (truth : JSONObject)) : Unit
+          (kotlin-member-call pushTruthAsync))
         (extern (truthStoreAppendJsonLineRaw
                   (store : TruthStore)
                   (file : File)
@@ -16345,6 +16350,65 @@
                   (truthStoreJsonTimeLocal remoteText)
                   remoteModified
                   (truthStoreFileLastModified local))))))
+        (def (truthStoreSaveTruthSnapshotLocal
+               (store : TruthStore)
+               (truth : JSONObject)) : File
+          (let ((validated
+                  (validatedSourceKey
+                    (truthSourceKey truth))))
+            (if (validatedSourceKeyPresent validated)
+              (let ((sourceKey
+                      (validatedSourceKeyOrEmpty validated)))
+                (let ((truthFile
+                        (truthStoreTruthPath store sourceKey))
+                      (pretty
+                        (truthStoreJsonToPrettyString
+                          truth
+                          (int32 2))))
+                  (begin
+                    (truthStoreAtomicWriteTextRaw
+                      store
+                      truthFile
+                      pretty)
+                    (truthStoreInvalidateTruthIndexRaw store)
+                    (let ((sessionId
+                            (truthSessionIdOr
+                              truth
+                              (truthSourceKeyOrUnknown sourceKey))))
+                      (let ((sessionDigest
+                              (truthStoreSha256Hex
+                                (textUtf8Bytes sessionId))))
+                        (begin
+                          (truthStoreAtomicWriteTextRaw
+                            store
+                            (truthStoreContainedLeaf
+                              (truthStoreReviewsDir store)
+                              (reviewFileName sessionDigest))
+                            pretty)
+                          (let ((event
+                                  (snapshotEventJson
+                                    sessionId
+                                    sourceKey
+                                    (truthStoreFileName truthFile))))
+                            (begin
+                              (truthStoreAppendJsonLineLocal
+                                store
+                                (truthStoreContainedLeaf
+                                  (truthStoreEventsDir store)
+                                  (eventsFileName sessionDigest))
+                                event)
+                              (truthStoreAppendJsonLineLocal
+                                store
+                                (truthStoreContainedLeaf
+                                  (truthStoreEventsDir store)
+                                  (allEventsFileName))
+                                event)
+                              (truthStoreRebuildLearnedExamplesRaw store)
+                              (truthStorePushTruthAsyncRaw store truth)
+                              truthFile))))))))
+              (throw
+                (truthStoreIllegalArgumentException "Invalid source key")
+                File))))
         (def (truthStoreMergeJsonLinesLocal
                (store : TruthStore)
                (file : File)
@@ -16488,23 +16552,8 @@
        "        truthStoreSaveSession(this, session)"
        ""
        "    @Synchronized"
-       "    fun saveTruthSnapshot(truth: JSONObject): File {"
-       "        val validatedSource = validatedSourceKey(truthSourceKey(truth))"
-       "        if (!validatedSourceKeyPresent(validatedSource)) throw IllegalArgumentException(\"Invalid source key\")"
-       "        val sourceKey = validatedSourceKeyOrEmpty(validatedSource)"
-       "        val truthFile = truthPath(sourceKey)"
-       "        atomicWriteText(truthFile, truth.toString(2))"
-       "        invalidateTruthIndex()"
-       "        val sessionId = truthSessionIdOr(truth, truthSourceKeyOrUnknown(sourceKey))"
-       "        val reviewFile = containedLeaf(reviewsDir, reviewFileName(sha256Hex(sessionId.toByteArray())))"
-       "        atomicWriteText(reviewFile, truth.toString(2))"
-       "        val event = snapshotEventJson(sessionId, sourceKey, truthFile.name)"
-       "        appendJsonLine(containedLeaf(eventsDir, eventsFileName(sha256Hex(sessionId.toByteArray()))), event)"
-       "        appendJsonLine(containedLeaf(eventsDir, allEventsFileName()), event)"
-       "        rebuildLearnedExamples()"
-       "        pushTruthAsync(truth)"
-       "        return truthFile"
-       "    }"
+       "    fun saveTruthSnapshot(truth: JSONObject): File ="
+       "        truthStoreSaveTruthSnapshotLocal(this, truth)"
        ""
        "    fun appendEvent(type: String, session: SsdSession, details: JSONObject = emptyJsonObject()) ="
        "        truthStoreAppendEvent(this, type, session, details)"
@@ -17001,7 +17050,7 @@
        "    internal fun appendJsonLine(file: File, json: JSONObject) ="
        "        truthStoreAppendJsonLineLocal(this, file, json)"
        ""
-       "    private fun pushTruthAsync(truth: JSONObject) {"
+       "    internal fun pushTruthAsync(truth: JSONObject) {"
        "        val payload = autosaveTruthPayloadJson(truth).toString()"
        "        runBackgroundNamed(\"sfb-truth-autosave\") {"
        "            try {"
diff --git a/tests/ssd-security-test.sh b/tests/ssd-security-test.sh
index 4633fdd..e820722 100755
--- a/tests/ssd-security-test.sh
+++ b/tests/ssd-security-test.sh
@@ -52,7 +52,7 @@ require_generated_text 'MessageDigest.isEqual'
 require_text 'setRequestProperty("Authorization", bearerAuthorizationHeader(config.bearerToken))'
 require_generated_text 'context.getSharedPreferences("ssd_review_remote", Context.MODE_PRIVATE)'
 require_text 'Remote SSD service is not locally configured'
-require_text 'validatedSourceKey'
+require_generated_text 'validatedSourceKey'
 require_generated_text 'truthStoreSha256Hex'
 require_generated_text 'textUtf8Bytes(key)'
 require_text 'StandardCopyOption.ATOMIC_MOVE'