Centralize SSD storage filenames in typed Kotlin

ober

c0be52a70788377309784d8ef4be3073a6d534ba

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 86ca3f7..7729cfb 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -1361,7 +1361,8 @@
                 StorageStats-bytes StorageStats-bytes-set!
                 storageSummaryText compressionRatioBudget boundedTreeReadLimit
                 boundedReadInitialCapacity mergedJsonLinesText
-                truthFileName reviewFileName eventsFileName
+                truthFileName reviewFileName eventsFileName allEventsFileName
+                learnedExamplesFileName
                 inputLimitExceededMessage outputLimitExceededMessage
                 clientLogHttpStatusMessage bearerAuthorizationHeader
                 zipEntryCountLimitExceededMessage httpStatusMessage
@@ -1404,6 +1405,10 @@
           (string-append
             "events-"
             (string-append hash ".events.jsonl")))
+        (def (allEventsFileName) : String
+          "all-events.jsonl")
+        (def (learnedExamplesFileName) : String
+          "group_examples.json")
         (def (inputLimitExceededMessage (limit : Int)) : String
           (string-append
             "Input exceeds "
@@ -7947,7 +7952,7 @@
        "        atomicWriteText(reviewFile, truth.toString(2))"
        "        val event = snapshotEventJson(sessionId, sourceKey, truthFile.name)"
        "        appendJsonLine(containedLeaf(eventsDir, eventsFileName(sha256Hex(sessionId.toByteArray()))), event)"
-       "        appendJsonLine(containedLeaf(eventsDir, \"all-events.jsonl\"), event)"
+       "        appendJsonLine(containedLeaf(eventsDir, allEventsFileName()), event)"
        "        rebuildLearnedExamples()"
        "        pushTruthAsync(truth)"
        "        return truthFile"
@@ -7956,7 +7961,7 @@
        "    fun appendEvent(type: String, session: SsdSession, details: JSONObject = emptyJsonObject()) {"
        "        val event = sessionEventJson(type, session, details)"
        "        appendJsonLine(containedLeaf(eventsDir, eventsFileName(sha256Hex(session.sessionId.toByteArray()))), event)"
-       "        appendJsonLine(containedLeaf(eventsDir, \"all-events.jsonl\"), event)"
+       "        appendJsonLine(containedLeaf(eventsDir, allEventsFileName()), event)"
        "    }"
        ""
 	       "    fun applyTruth(session: SsdSession) {"
@@ -8267,7 +8272,7 @@
        "    }"
        ""
        "    fun applyLearnedGuesses(session: SsdSession): Int {"
-       "        val file = File(learnedDir, \"group_examples.json\")"
+       "        val file = File(learnedDir, learnedExamplesFileName())"
        "        if (!fileExists(file)) rebuildLearnedExamples()"
        "        if (!fileExists(file)) return 0"
        "        val examples = learnedExamplesFromDocument(jsonObjectFromText(readLocalText(file)))"
@@ -8336,7 +8341,7 @@
        "        } finally {"
        "            stage.deleteRecursively()"
        "        }"
-       "        if (count > 0 || !File(learnedDir, \"group_examples.json\").exists()) {"
+       "        if (count > 0 || !File(learnedDir, learnedExamplesFileName()).exists()) {"
        "            rebuildLearnedExamples()"
        "        }"
        "        return count"
@@ -8491,7 +8496,7 @@
        "            if (learnedExamplesCount(examples) >= MAX_LEARNED_EXAMPLES) break@fileLoop"
        "        }"
        "        val learned = learnedExamplesDocument(examples, MAX_LEARNED_EXAMPLES)"
-       "        atomicWriteText(containedLeaf(learnedDir, \"group_examples.json\"), learned.toString(2))"
+       "        atomicWriteText(containedLeaf(learnedDir, learnedExamplesFileName()), learned.toString(2))"
        "    }"
        ""
        "    private fun seedBundledTruth(): Int {"