diff --git a/CHANGELOG.md b/CHANGELOG.md
index d455059..650ff91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## [Unreleased]
+
+### Added
+
+- Krill tars can now be used as *input* and updated in place of a full re-export ("merge mode"): listing an existing `.krill.tar` among the inputs with `-t krill` streams it to a new tar (`<name>.updated.krill.tar`, or `-o`), updated from the remaining inputs. Two use cases: (1) adding or fixing metadata (stand-off `<standOff>` files, `<xenoData>`, header ZIPs) when the original KorAP-XML ZIPs are no longer available, and (2) replacing or adding single annotation foundries (e.g. an improved wiki-taxonomy topic-domain classification) without touching the rest. Texts unaffected by the new inputs are copied through byte-identically without being decompressed; affected texts are patched surgically at the JSON level and recompressed in parallel, and end up identical to a full re-export with the same inputs. New metadata fields replace same-key fields (including legacy/corrected name pairs such as `textClass`/`dmozDomain`) and are appended otherwise; `creationDate`/`pubDate` are only replaced when a new text-level header is supplied, so corpus-level headers cannot clobber per-text dates. Texts present in the new inputs but missing from the tar are ignored with a warning; base tokenization/structure entries are ignored as well. Tars produced by korapxml2krill (Perl) are supported. The input tar is never modified, and the regular Krill export path is unchanged.
+
 ## [v4.1.0] - 2026-06-19
 
 ### Added
diff --git a/Readme.md b/Readme.md
index 2e43976..74ac4c1 100644
--- a/Readme.md
+++ b/Readme.md
@@ -193,6 +193,44 @@
   | docker run --rm -i korap/wiki-taxonomy > rei_sample.wikiDomain.meta.xml
 ```
 
+### Updating an existing Krill tar (merge mode)
+
+An existing Krill tar can also be used as *input* and updated with new metadata
+and/or annotation foundries — useful when the original KorAP-XML ZIPs are no longer
+at hand, or when a single annotation foundry (e.g. an improved topic-domain
+classification) must be fixed without re-running the whole conversion. Merge mode is
+switched on simply by listing a `.tar` file among the inputs:
+
+```shell script
+# Update/add a stand-off classification in an existing Krill tar
+./build/bin/korapxmltool -t krill -D out/krill \
+  out/krill/rei_sample.krill.tar rei_sample.wikiDomain.meta.xml
+
+# Replace (or add) the TreeTagger annotations in an existing Krill tar
+./build/bin/korapxmltool -t krill -D out/krill \
+  out/krill/rei_sample.krill.tar app/src/test/resources/rei_sample.tree_tagger.zip
+```
+
+The result is written to a new tar (`<name>.updated.krill.tar`, or the path given
+with `-o`); the input tar is never modified, so an interrupted run cannot damage
+existing data. Properties of the merge:
+
+- Texts not affected by the new inputs are copied through byte-identically, without
+  even being decompressed; affected texts are patched and recompressed in parallel.
+- Every foundry contained in the supplied annotation ZIPs is treated as
+  authoritative: its existing annotations are replaced entirely; other foundries are
+  left untouched. The patched texts are identical to what a full re-export with the
+  same inputs would produce.
+- Metadata fields from stand-off files, `<xenoData>` and header ZIPs replace fields
+  with the same key and are appended otherwise. `creationDate`/`pubDate` are only
+  replaced when a new *text-level* header is supplied, so corpus-level headers cannot
+  clobber per-text dates.
+- Texts present in the new inputs but missing from the tar are ignored with a
+  warning. The base tokenization of the tar cannot be changed:
+  `data.xml`/`tokens.xml`/`structure.xml` entries are ignored as well.
+- Tars produced by korapxml2krill (Perl) are supported; untouched texts and
+  annotations keep their exact original form.
+
 ## Annotation
 
 ### Tagging with integrated MarMoT POS tagger directly to a new KorAP-XML ZIP file
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
index bfdd882..520ad94 100644
--- a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
@@ -4,6 +4,7 @@
 import de.ids_mannheim.korapxmltools.AnnotationToolBridgeFactory.Companion.taggerFoundries
 import de.ids_mannheim.korapxmltools.formatters.KorapXmlFormatter
 import de.ids_mannheim.korapxmltools.formatters.KrillJsonGenerator
+import de.ids_mannheim.korapxmltools.formatters.KrillJsonPatcher
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry
 import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream
 import org.apache.commons.compress.archivers.zip.Zip64Mode
@@ -121,7 +122,7 @@
     private var targetZipFileName: String? = null
     // Locale is now globally forced to ROOT at startup (see main())
 
-    @Parameters(arity = "0..*", description = ["Input files: KorAP-XML ZIP files or CoNLL-U files (.conllu). If omitted, reads from stdin (requires -o for output path)."])
+    @Parameters(arity = "0..*", description = ["Input files: KorAP-XML ZIP files, CoNLL-U files (.conllu), stand-off metadata XML files, or (with -t krill) an existing Krill tar to update from the other inputs. If omitted, reads from stdin (requires -o for output path)."])
     var zipFileNames: Array<String>? = null
 
     @Option(
@@ -836,6 +837,26 @@
                 }
             }
 
+            // An existing Krill tar among the inputs switches on merge mode: the tar is
+            // streamed to a new tar, updated from the remaining inputs (KorAP-XML ZIPs
+            // and/or stand-off metadata files).
+            zipFileNames?.filter { it.endsWith(".tar") }?.takeIf { it.isNotEmpty() }?.let { tarInputs ->
+                if (outputFormat != OutputFormat.KRILL) {
+                    throw ParameterException(spec.commandLine(),
+                        "Krill tar input is only supported with -f krill")
+                }
+                if (tarInputs.size > 1) {
+                    throw ParameterException(spec.commandLine(),
+                        "Only one Krill tar can be updated per invocation, got: ${tarInputs.joinToString(", ")}")
+                }
+                krillInputTarPath = tarInputs[0]
+                zipFileNames = zipFileNames!!.filterNot { it in tarInputs }.toTypedArray()
+                if (zipFileNames!!.isEmpty() && standoffMetadata.isEmpty()) {
+                    throw ParameterException(spec.commandLine(),
+                        "Updating a Krill tar requires at least one KorAP-XML ZIP or stand-off metadata file with new data")
+                }
+            }
+
             // For krill format, redirect logging to file before any logging occurs
             if (outputFormat == OutputFormat.KRILL) {
                 // Determine output path for Krill format
@@ -848,6 +869,10 @@
                     } else {
                         "$finalOutputPath.tar"
                     }
+                } else if (krillInputTarPath != null) {
+                    // Merge mode: never overwrite the input tar by default
+                    val baseName = File(krillInputTarPath!!).name.replace(Regex("(\\.krill)?\\.tar$"), "")
+                    File(outputDir, "$baseName.updated.krill.tar").absolutePath
                 } else {
                     // Find the base ZIP (one without a foundry suffix)
                     val baseZip = zipFileNames!!.firstOrNull { zip ->
@@ -904,8 +929,13 @@
             // not to the console, so it does not clutter stderr output.
             logCallOptionsAndEnvironment()
 
+            // Krill tar merge mode: update an existing Krill tar from the remaining inputs
+            if (krillInputTarPath != null) {
+                return mergeKrillTar(krillInputTarPath!!, zipFileNames ?: emptyArray())
+            }
+
             // CoNLL-U to KorAP XML ZIP conversion mode
-            val isConlluInput = zipFileNames == null || zipFileNames!!.isEmpty() || 
+            val isConlluInput = zipFileNames == null || zipFileNames!!.isEmpty() ||
                                zipFileNames!!.any { it.endsWith(".conllu") }
             
             if (isConlluInput) {
@@ -1245,6 +1275,8 @@
     var krillTarOutputStream: TarArchiveOutputStream? = null
     var krillOutputFileName: String? = null
     private var krillOutputPath: String? = null
+    // Set when an existing Krill tar is given as input (merge mode)
+    private var krillInputTarPath: String? = null
     private var textOutputWriter: BufferedWriter? = null
 
     // Fast DocumentBuilderFactory without security features (safe for trusted input)
@@ -2151,44 +2183,7 @@
                 val headerEntries = allEntries.filter { it.name.contains("header.xml") }
                 
                 headerEntries.forEach { headerEntry ->
-                    try {
-                        val headerBytes = foundryData.zipFile.getInputStream(headerEntry).readBytes()
-                        val headerDoc = safeDomFactory.newDocumentBuilder().parse(ByteArrayInputStream(headerBytes))
-                        val headerRoot = headerDoc.documentElement
-                        headerRoot.normalize()
-
-                        val entryPath = headerEntry.name
-                        val pathParts = entryPath.split('/').filter { it.isNotEmpty() && !it.endsWith("header.xml") }
-
-                        var textSigle = headerRoot.firstText("textSigle")
-                        var docSigle = headerRoot.firstText("dokumentSigle")
-                        var corpusSigle = headerRoot.firstText("korpusSigle")
-
-                        if (textSigle == null && docSigle == null && corpusSigle == null) {
-                            if (pathParts.size == 1) {
-                                corpusSigle = pathParts[0]
-                            } else if (pathParts.size == 2) {
-                                docSigle = "${pathParts[0]}/${pathParts[1]}"
-                            } else if (pathParts.size >= 3) {
-                                textSigle = getTextIdFromPath(entryPath)
-                            }
-                        }
-
-                        val docId = textSigle?.replace('/', '_')
-
-                        // Call appropriate metadata collection function based on what the header contains
-                        if (corpusSigle != null) {
-                            collectCorpusMetadata(corpusSigle, headerRoot)
-                        }
-                        if (docSigle != null) {
-                            collectDocMetadata(docSigle, headerRoot)
-                        }
-                        if (docId != null) {
-                            collectKrillMetadata(docId, headerRoot)
-                        }
-                    } catch (e: Exception) {
-                        LOGGER.warning("Error processing header ${headerEntry.name}: ${e.message}")
-                    }
+                    processKrillHeaderEntry(foundryData.zipFile, headerEntry)
                 }
             }
             LOGGER.info("Completed header processing for metadata")
@@ -2225,6 +2220,303 @@
     }
     
     /**
+     * Parse a corpus-, document- or text-level header.xml entry and feed the
+     * corpus/doc/text metadata collectors. Shared between the interleaved Krill
+     * flow and Krill tar merge mode.
+     */
+    private fun processKrillHeaderEntry(zipFile: ApacheZipFile, headerEntry: ZipArchiveEntry) {
+        try {
+            val headerBytes = zipFile.getInputStream(headerEntry).readBytes()
+            val headerDoc = safeDomFactory.newDocumentBuilder().parse(ByteArrayInputStream(headerBytes))
+            val headerRoot = headerDoc.documentElement
+            headerRoot.normalize()
+
+            val entryPath = headerEntry.name
+            val pathParts = entryPath.split('/').filter { it.isNotEmpty() && !it.endsWith("header.xml") }
+
+            var textSigle = headerRoot.firstText("textSigle")
+            var docSigle = headerRoot.firstText("dokumentSigle")
+            var corpusSigle = headerRoot.firstText("korpusSigle")
+
+            if (textSigle == null && docSigle == null && corpusSigle == null) {
+                if (pathParts.size == 1) {
+                    corpusSigle = pathParts[0]
+                } else if (pathParts.size == 2) {
+                    docSigle = "${pathParts[0]}/${pathParts[1]}"
+                } else if (pathParts.size >= 3) {
+                    textSigle = getTextIdFromPath(entryPath)
+                }
+            }
+
+            val docId = textSigle?.replace('/', '_')
+
+            // Call appropriate metadata collection function based on what the header contains
+            if (corpusSigle != null) {
+                collectCorpusMetadata(corpusSigle, headerRoot)
+            }
+            if (docSigle != null) {
+                collectDocMetadata(docSigle, headerRoot)
+            }
+            if (docId != null) {
+                collectKrillMetadata(docId, headerRoot)
+            }
+        } catch (e: Exception) {
+            LOGGER.warning("Error processing header ${headerEntry.name}: ${e.message}")
+        }
+    }
+
+    // ------------------------------------------------------------------
+    // Krill tar merge mode
+    // ------------------------------------------------------------------
+
+    /** Text id in the lossy form used for Krill tar entry names ("REI_RBR.00473" -> "REI-RBR-00473"). */
+    private fun normalizeKrillTextId(textId: String): String =
+        textId.replace("_", "-").replace(".", "-")
+
+    /**
+     * Update an existing Krill tar from KorAP-XML ZIPs (annotation foundries and/or
+     * headers) and stand-off metadata files, streaming it into a new tar.
+     *
+     * Texts present in the new inputs but absent from the tar are ignored with a
+     * warning. The base tokenization of the tar texts cannot be changed, so
+     * data.xml/tokens.xml/structure.xml entries are ignored as well.
+     */
+    private fun mergeKrillTar(inputTarPath: String, zips: Array<String>): Int {
+        val inputTar = File(inputTarPath)
+        val outputTar = File(krillOutputPath!!)
+        krillOutputFileName = outputTar.absolutePath
+        if (inputTar.canonicalFile == outputTar.canonicalFile) {
+            LOGGER.severe("Refusing to overwrite the input tar $inputTarPath in place; use -o to choose a different output file")
+            return 1
+        }
+        if (outputTar.exists() && !overwrite) {
+            LOGGER.severe("Output file ${outputTar.path} already exists. Use --force to overwrite.")
+            return 1
+        }
+        outputTar.parentFile?.mkdirs()
+        outputTexts.clear()
+        krillData.clear()
+
+        data class MergeZip(val path: String, val foundry: String, val zipFile: ApacheZipFile)
+
+        val mergeZips = mutableListOf<MergeZip>()
+        // Annotation-layer entries grouped by normalized text id: (zip, docId, entry)
+        val annotationWork = HashMap<String, MutableList<Triple<MergeZip, String, ZipArchiveEntry>>>()
+        var ignoredBaseContentEntries = 0
+        val annotationRegex = Regex(".*(morpho|dependency|sentences|constituency)\\.xml$")
+        val baseContentRegex = Regex(".*(data|tokens|structure)\\.xml$")
+
+        try {
+            zips.forEach { zipPath ->
+                val zipFoundry = getFoundryFromZipFileName(zipPath)
+                val zipFile = try {
+                    openZipFile(zipPath)
+                } catch (e: Exception) {
+                    LOGGER.severe("Failed to open ZIP $zipPath: ${e.message}")
+                    return 1
+                }
+                val mergeZip = MergeZip(zipPath, zipFoundry, zipFile)
+                mergeZips.add(mergeZip)
+                zipFile.entries.asSequence().filter { !it.isDirectory }.forEach { entry ->
+                    val name = entry.name
+                    // Foundry directory of the entry ("<text>/<foundry>/<file>.xml")
+                    val entryDir = name.substringBeforeLast('/', "").substringAfterLast('/')
+                    when {
+                        name.endsWith("header.xml") -> processKrillHeaderEntry(zipFile, entry)
+                        name.matches(annotationRegex) && entryDir != "base" -> {
+                            val docId = getTextIdFromPath(name)
+                            annotationWork.getOrPut(normalizeKrillTextId(docId)) { mutableListOf() }
+                                .add(Triple(mergeZip, docId, entry))
+                        }
+                        name.matches(baseContentRegex) || name.matches(annotationRegex) ->
+                            ignoredBaseContentEntries++
+                    }
+                }
+            }
+            if (ignoredBaseContentEntries > 0) {
+                LOGGER.warning(
+                    "Merge mode cannot change the base tokenization or structure of texts in the tar: " +
+                        "ignoring $ignoredBaseContentEntries data/tokens/structure/base entries"
+                )
+            }
+
+            // Texts with a text-level header in the new inputs (their date fields may be replaced)
+            val textsWithNewHeader = krillData.keys.toSet()
+            val corpusDocMetaProvided = corpusMetadata.isNotEmpty() || docMetadata.isNotEmpty() ||
+                corpusXenoData.isNotEmpty() || docXenoData.isNotEmpty()
+
+            // Normalized text id -> original id, for all texts with per-text metadata updates
+            val textMetaByNorm = HashMap<String, String>()
+            (textsWithNewHeader + standoffMetadata.keys + textXenoData.keys).forEach { docId ->
+                val norm = normalizeKrillTextId(docId)
+                val previous = textMetaByNorm.put(norm, docId)
+                if (previous != null && previous != docId) {
+                    LOGGER.warning("Ambiguous text ids $previous and $docId both normalize to tar entry name $norm")
+                }
+            }
+
+            LOGGER.info(
+                "Updating Krill tar $inputTarPath -> ${outputTar.path}: " +
+                    "${annotationWork.size} texts with new annotations, " +
+                    "${textMetaByNorm.size} texts with new per-text metadata, " +
+                    "corpus/doc-level metadata provided: $corpusDocMetaProvided"
+            )
+
+            val mergeProgressBar = if (!quiet) ProgressBarBuilder()
+                .setTaskName(outputTar.name)
+                .setInitialMax(inputTar.length())
+                .setStyle(ProgressBarStyle.COLORFUL_UNICODE_BAR)
+                .setUpdateIntervalMillis(500)
+                .setUnit(" MB", 1L shl 20)
+                .showSpeed()
+                .build() else null
+
+            val patcher = KrillTarMerger.TextPatcher { normId ->
+                val textMetaDocId = textMetaByNorm[normId]
+                val annotationEntries = annotationWork[normId]
+                if (!corpusDocMetaProvided && textMetaDocId == null && annotationEntries == null) {
+                    null
+                } else {
+                    { json ->
+                        patchKrillText(json, normId, textMetaDocId, textsWithNewHeader,
+                            annotationEntries?.map { (mz, docId, entry) ->
+                                Triple(mz.zipFile to mz.path, mz.foundry to docId, entry)
+                            })
+                    }
+                }
+            }
+
+            val stats = try {
+                KrillTarMerger(LOGGER, maxThreads).merge(inputTar, outputTar, patcher) { bytesRead ->
+                    mergeProgressBar?.stepTo(bytesRead)
+                }
+            } finally {
+                mergeProgressBar?.close()
+            }
+
+            // Texts in the new inputs that the tar does not contain are ignored with a warning
+            val unmatchedNorms = (textMetaByNorm.keys + annotationWork.keys) - stats.seenTextIds
+            if (unmatchedNorms.isNotEmpty()) {
+                val displayIds = unmatchedNorms.map { norm ->
+                    textMetaByNorm[norm] ?: annotationWork[norm]?.firstOrNull()?.second ?: norm
+                }.sorted()
+                displayIds.take(20).forEach { docId ->
+                    LOGGER.warning("Ignoring text $docId from the new input(s): not present in $inputTarPath")
+                }
+                if (displayIds.size > 20) {
+                    LOGGER.warning("... and ${displayIds.size - 20} more texts not present in $inputTarPath")
+                }
+                LOGGER.warning("Ignored ${displayIds.size} text(s) from the new input(s) that are not in the input tar")
+            }
+
+            LOGGER.info(
+                "Krill tar update complete: ${stats.entries} entries " +
+                    "(${stats.patched} updated, ${stats.copied} copied unchanged) -> ${outputTar.path}"
+            )
+            return 0
+        } finally {
+            mergeZips.forEach { mz ->
+                try {
+                    mz.zipFile.close()
+                } catch (e: Exception) {
+                    LOGGER.warning("Failed to close ZIP ${mz.path}: ${e.message}")
+                }
+            }
+        }
+    }
+
+    /**
+     * Patch a single text's Krill JSON: merge new metadata fields (from headers,
+     * stand-off metadata and xenodata) and replace/add annotation foundries.
+     * Runs on merge worker threads; per-text state is keyed by docId so
+     * concurrent texts don't interfere.
+     */
+    private fun patchKrillText(
+        json: String,
+        normId: String,
+        textMetaDocId: String?,
+        textsWithNewHeader: Set<String>,
+        annotationEntries: List<Triple<Pair<ApacheZipFile, String>, Pair<String, String>, ZipArchiveEntry>>?
+    ): String {
+        // Recover the real text id: the entry file name is lossy, the JSON's own
+        // textSigle ("REI/RBR/00473") is authoritative.
+        val sigle = KrillJsonPatcher.extractTextSigle(json)
+        val docId = when {
+            sigle != null && sigle.count { it == '/' } >= 2 ->
+                sigle.replaceFirst("/", "_").replaceFirst("/", ".")
+            sigle != null -> sigle.replace('/', '_')
+            else -> textMetaDocId ?: annotationEntries?.firstOrNull()?.second?.second
+        }
+        if (docId == null) {
+            LOGGER.warning("Cannot determine text id for tar entry $normId; leaving it unchanged")
+            return json
+        }
+
+        var result = json
+
+        // ---- metadata fields ----
+        val stub = KrillJsonGenerator.KrillTextData(textId = docId)
+        (krillData[docId] ?: textMetaDocId?.let { krillData[it] })
+            ?.headerMetadata?.let { stub.headerMetadata.putAll(it) }
+
+        val corpusSigle = docId.substringBefore('_')
+        val docSigle = "$corpusSigle/${docId.substringAfter('_').substringBefore('.')}"
+        val combinedStandoff = mutableListOf<KrillJsonGenerator.StandoffField>()
+        (standoffMetadata[docId] ?: textMetaDocId?.let { standoffMetadata[it] })
+            ?.let { combinedStandoff.addAll(it) }
+        corpusXenoData[corpusSigle]?.let { combinedStandoff.addAll(it) }
+        docXenoData[docSigle]?.let { combinedStandoff.addAll(it) }
+        (textXenoData[docId] ?: textMetaDocId?.let { textXenoData[it] })
+            ?.let { combinedStandoff.addAll(it) }
+        stub.standoffFields = combinedStandoff
+
+        val fieldEntries = KrillJsonGenerator.buildMetadataFieldEntries(
+            stub, corpusMetadata, docMetadata, legacyFieldNames
+        )
+        val hasNewTextHeader = docId in textsWithNewHeader ||
+            (textMetaDocId != null && textMetaDocId in textsWithNewHeader)
+        val fieldPatches = fieldEntries.mapNotNull { entry ->
+            when {
+                // Sigle fields are identity, never touched in a merge
+                entry.origin == KrillJsonGenerator.FieldOrigin.SIGLE -> null
+                // Dates inherited from corpus/doc headers must not clobber per-text
+                // dates in the tar; only a new text-level header may replace them.
+                entry.origin == KrillJsonGenerator.FieldOrigin.HEADER &&
+                    (entry.key == "creationDate" || entry.key == "pubDate") && !hasNewTextHeader ->
+                    KrillJsonPatcher.FieldPatch(entry.key, entry.json, KrillJsonPatcher.FieldMode.APPEND_IF_MISSING)
+                else ->
+                    KrillJsonPatcher.FieldPatch(entry.key, entry.json, KrillJsonPatcher.FieldMode.REPLACE_OR_APPEND)
+            }
+        }
+        if (fieldPatches.isNotEmpty()) {
+            result = KrillJsonPatcher.patchFields(result, fieldPatches)
+        }
+
+        // ---- annotation foundries ----
+        if (!annotationEntries.isNullOrEmpty()) {
+            val entryDocId = annotationEntries.first().second.second
+            annotationEntries.forEach { (zipInfo, foundryInfo, entry) ->
+                processZipEntry(zipInfo.first, zipInfo.second, foundryInfo.first, entry, false)
+            }
+            val textData = krillData[entryDocId]
+            if (textData != null) {
+                result = KrillJsonPatcher.patchFoundries(result, textData)
+            } else {
+                LOGGER.warning("No annotation data collected for $entryDocId; foundries unchanged")
+            }
+            // Free per-text state
+            krillData.remove(entryDocId)
+            fnames.remove(entryDocId)
+            sentences.remove(entryDocId)
+            tokens.remove(entryDocId)
+            texts.remove(entryDocId)
+            morpho.remove(entryDocId)
+        }
+
+        return result
+    }
+
+    /**
      * Submit a single text's entries for a specific foundry to the work-stealing queue.
      */
     private fun submitTextForFoundry(zipFile: ApacheZipFile, zipPath: String, foundry: String, textId: String, textEntries: List<ZipArchiveEntry>) {
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KrillTarMerger.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KrillTarMerger.kt
new file mode 100644
index 0000000..a1e8134
--- /dev/null
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KrillTarMerger.kt
@@ -0,0 +1,170 @@
+package de.ids_mannheim.korapxmltools
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream
+import java.io.BufferedInputStream
+import java.io.BufferedOutputStream
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.ArrayBlockingQueue
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+import java.util.concurrent.Future
+import java.util.concurrent.ThreadPoolExecutor
+import java.util.concurrent.TimeUnit
+import java.util.logging.Logger
+import java.util.zip.GZIPInputStream
+import java.util.zip.GZIPOutputStream
+
+/**
+ * Updates an existing Krill tar from new inputs by streaming it entry by entry
+ * ("merge mode", see KrillJsonPatcher).
+ *
+ * Entries that are not affected by the update are copied through without even
+ * being decompressed, so they stay byte-identical and cost only I/O. Affected
+ * entries are decompressed, patched and recompressed on a worker pool while the
+ * main thread keeps reading and writing, preserving the original entry order
+ * with bounded memory (at most a few texts in flight).
+ *
+ * The output is always a new tar file; the input tar is never modified, so an
+ * interrupted merge cannot damage existing data.
+ */
+class KrillTarMerger(
+    private val logger: Logger,
+    private val threads: Int
+) {
+    fun interface TextPatcher {
+        /**
+         * Return a JSON patch function for the tar entry with this normalized text id
+         * (the entry base name, e.g. "REI-RBR-00473"), or null when the text is not
+         * affected and its bytes should be copied through unchanged.
+         */
+        fun patcherFor(normalizedTextId: String): ((String) -> String)?
+    }
+
+    data class Stats(
+        var entries: Int = 0,
+        var patched: Int = 0,
+        var copied: Int = 0,
+        val seenTextIds: MutableSet<String> = mutableSetOf()
+    )
+
+    private class OutEntry(val name: String, val modTime: Long, val bytes: Future<ByteArray>)
+
+    /**
+     * Stream [inputTar] to [outputTar], patching affected texts via [patcher].
+     * [onProgress] is called after each written entry with the number of bytes
+     * read from the input tar so far.
+     */
+    fun merge(
+        inputTar: File,
+        outputTar: File,
+        patcher: TextPatcher,
+        onProgress: ((bytesRead: Long) -> Unit)? = null
+    ): Stats {
+        val stats = Stats()
+        val pool: ExecutorService = Executors.newFixedThreadPool(threads.coerceAtLeast(1)) { r ->
+            Thread(r, "KrillMergeWorker").apply { isDaemon = true }
+        }
+        // Bounded number of in-flight patch jobs keeps memory flat on huge tars.
+        val maxInFlight = (threads.coerceAtLeast(1)) * 2 + 1
+        val pending = ArrayDeque<OutEntry>()
+
+        try {
+            TarArchiveInputStream(BufferedInputStream(FileInputStream(inputTar), 1 shl 20)).use { tarIn ->
+                TarArchiveOutputStream(BufferedOutputStream(FileOutputStream(outputTar), 1 shl 20)).use { tarOut ->
+                    tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX)
+
+                    fun drainOne() {
+                        val out = pending.removeFirst()
+                        val bytes = out.bytes.get()
+                        val entry = TarArchiveEntry(out.name)
+                        entry.size = bytes.size.toLong()
+                        entry.setModTime(out.modTime)
+                        tarOut.putArchiveEntry(entry)
+                        tarOut.write(bytes)
+                        tarOut.closeArchiveEntry()
+                        onProgress?.invoke(tarIn.bytesRead)
+                    }
+
+                    var entry: TarArchiveEntry? = tarIn.nextEntry
+                    while (entry != null) {
+                        if (!entry.isFile) {
+                            entry = tarIn.nextEntry
+                            continue
+                        }
+                        stats.entries++
+                        val name = entry.name
+                        val baseName = name.substringAfterLast('/')
+                        val compression = when {
+                            baseName.endsWith(".json.gz") -> Compression.GZIP
+                            baseName.endsWith(".json.lz4") -> Compression.LZ4
+                            else -> null
+                        }
+                        val normalizedId = when (compression) {
+                            Compression.GZIP -> baseName.removeSuffix(".json.gz")
+                            Compression.LZ4 -> baseName.removeSuffix(".json.lz4")
+                            null -> null
+                        }
+                        if (normalizedId != null) {
+                            stats.seenTextIds.add(normalizedId)
+                        }
+                        val patchFn = normalizedId?.let { patcher.patcherFor(it) }
+                        // The entry's bytes must be consumed before advancing to the next
+                        // entry, so reading happens here; only patching is parallel.
+                        val raw = tarIn.readAllBytes()
+                        val modTime = entry.lastModifiedDate.time
+
+                        if (patchFn == null || compression == null) {
+                            stats.copied++
+                            pending.addLast(OutEntry(name, modTime, java.util.concurrent.CompletableFuture.completedFuture(raw)))
+                        } else {
+                            stats.patched++
+                            pending.addLast(OutEntry(name, modTime, pool.submit<ByteArray> {
+                                recompress(patchFn(decompress(raw, compression)), compression)
+                            }))
+                        }
+                        while (pending.size >= maxInFlight) drainOne()
+                        entry = tarIn.nextEntry
+                    }
+                    while (pending.isNotEmpty()) drainOne()
+                    tarOut.finish()
+                }
+            }
+        } finally {
+            pool.shutdownNow()
+        }
+        return stats
+    }
+
+    private enum class Compression { GZIP, LZ4 }
+
+    private fun decompress(bytes: ByteArray, compression: Compression): String {
+        val input = when (compression) {
+            Compression.GZIP -> GZIPInputStream(ByteArrayInputStream(bytes))
+            Compression.LZ4 -> net.jpountz.lz4.LZ4FrameInputStream(ByteArrayInputStream(bytes))
+        }
+        return input.use { it.readAllBytes().toString(StandardCharsets.UTF_8) }
+    }
+
+    private fun recompress(json: String, compression: Compression): ByteArray {
+        val byteOut = ByteArrayOutputStream(json.length / 2)
+        val out = when (compression) {
+            // Same gzip level as KorapXmlTool.compressKrillJson, so patched entries
+            // match what a fresh krill export would produce.
+            Compression.GZIP -> object : GZIPOutputStream(byteOut) {
+                init {
+                    def.setLevel(1)
+                }
+            }
+            Compression.LZ4 -> net.jpountz.lz4.LZ4FrameOutputStream(byteOut)
+        }
+        out.use { it.write(json.toByteArray(StandardCharsets.UTF_8)) }
+        return byteOut.toByteArray()
+    }
+}
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonGenerator.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonGenerator.kt
index a7540c0..6568d0b 100644
--- a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonGenerator.kt
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonGenerator.kt
@@ -3,6 +3,7 @@
 import de.ids_mannheim.korapxmltools.KorapXmlTool.MorphoSpan
 import de.ids_mannheim.korapxmltools.KorapXmlTool.Span
 import de.ids_mannheim.korapxmltools.NonBmpString
+import java.util.SortedSet
 import java.util.logging.Logger
 
 /**
@@ -100,6 +101,281 @@
         return sb.toString()
     }
 
+    /** Short layer prefix used in the token stream and layerInfos, or null for "base". */
+    fun foundryPrefix(foundry: String): String? = when (foundry) {
+        "base" -> null
+        "tree_tagger" -> "tt"
+        "marmot-malt" -> "marmot"
+        else -> foundry
+    }
+
+    /** Full foundry name used in the "foundries" summary string. */
+    fun foundryFullNameForPrefix(prefix: String): String =
+        if (prefix == "tt") "treetagger" else prefix
+
+    /**
+     * Layer descriptors (e.g. "p=tokens", "d=rels") a foundry's morpho data
+     * contributes to layerInfos. Shared between [generateTo] and the tar merge path.
+     */
+    fun computeFoundryLayers(foundry: String, morphoData: Collection<MorphoSpan>?): SortedSet<String> {
+        val layers = sortedSetOf<String>()
+
+        // Check if this foundry has dependency annotations
+        val hasDependencies = morphoData?.any {
+            it.head != null && it.head != "_" && it.deprel != null && it.deprel != "_"
+        } ?: false
+
+        if (hasDependencies) {
+            layers.add("d=rels")
+        }
+
+        // Check if this foundry has lemma annotations
+        val hasLemma = morphoData?.any {
+            it.lemma != null && it.lemma != "_"
+        } ?: false
+        if (hasLemma) {
+            layers.add("l=tokens")
+        }
+
+        // Check if this foundry has POS annotations (xpos or upos)
+        val hasPos = morphoData?.any {
+            (it.xpos != null && it.xpos != "_") || (it.upos != null && it.upos != "_")
+        } ?: false
+        if (hasPos) {
+            layers.add("p=tokens")
+        }
+
+        // Check if this foundry has morphological features
+        val hasFeatures = morphoData?.any {
+            it.feats != null && it.feats != "_"
+        } ?: false
+        if (hasFeatures) {
+            layers.add("m=tokens")
+        }
+
+        // Check if this foundry has UPOS (skip for tree_tagger)
+        if (foundry != "tree_tagger") {
+            val hasUpos = morphoData?.any {
+                it.upos != null && it.upos != "_"
+            } ?: false
+            if (hasUpos) {
+                layers.add("u=tokens")
+            }
+        }
+
+        // Extra inline w-attribute layers (norm, orig, phon, trans) are
+        // rare; a single short-circuiting scan gates the four per-attribute
+        // checks so corpora without them pay at most one extra pass.
+        val hasExtra = morphoData?.any {
+            (it.norm != null && it.norm != "_") || (it.orig != null && it.orig != "_") ||
+            (it.phon != null && it.phon != "_") || (it.trans != null && it.trans != "_")
+        } ?: false
+        if (hasExtra) {
+            // hasExtra is only true when morphoData is non-null, so the
+            // compiler smart-casts it here (no safe call needed).
+            if (morphoData.any { it.norm != null && it.norm != "_" }) layers.add("norm=tokens")
+            if (morphoData.any { it.orig != null && it.orig != "_" }) layers.add("orig=tokens")
+            if (morphoData.any { it.phon != null && it.phon != "_" }) layers.add("phon=tokens")
+            if (morphoData.any { it.trans != null && it.trans != "_" }) layers.add("trans=tokens")
+        }
+        return layers
+    }
+
+    /** Resolve a CoNLL-U or offset-based head reference to a 0-based token index, or null. */
+    internal fun resolveHeadIndex(headStr: String, offsetToIndex: Map<String, Int>): Int? =
+        if (headStr.contains("-")) {
+            offsetToIndex[headStr]
+        } else {
+            val idx = headStr.toIntOrNull()
+            if (idx != null && idx > 0) idx - 1 else null
+        }
+
+    internal fun isRootHead(headStr: String): Boolean =
+        headStr == "0" || (headStr.contains("-") && headStr.startsWith("0-"))
+
+    /** Inverse dependency edge annotation ("<:foundry/d:rel$<b>32<i>dependent"). */
+    internal fun inverseDependencyAnnotation(prefix: String, deprel: String, dependentIndex: Int): String =
+        "<:$prefix/d:${deprel.escapeKrillValue()}\$<b>32<i>$dependentIndex"
+
+    /** Span annotation for a structural span whose token range is already resolved. */
+    internal fun structureSpanAnnotation(span: StructureSpan): String =
+        if (span.attributes.isEmpty()) {
+            "<>:${span.layer}\$<b>64<i>${span.from}<i>${span.to}<i>${span.tokenTo}<b>${span.depth}"
+        } else {
+            "<>:${span.layer}\$<b>64<i>${span.from}<i>${span.to}<i>${span.tokenTo}<b>${span.depth}<s>${span.depth}"
+        }
+
+    /**
+     * Resolve tokenFrom/tokenTo (exclusive) of a structural span against the token
+     * list, mirroring the resolution used during full generation.
+     */
+    fun resolveStructureSpanTokenRange(span: StructureSpan, tokens: List<Span>): StructureSpan {
+        if (span.tokenFrom >= 0 && span.tokenTo >= 0) {
+            return span
+        }
+        var tokenFrom = lowerBoundTokenFrom(tokens, span.from)
+        if (tokenFrom >= tokens.size || tokens[tokenFrom].from >= span.to) {
+            tokenFrom = -1
+        }
+
+        var lastTokenIndex = upperBoundTokenTo(tokens, span.to) - 1
+        if (lastTokenIndex < 0 || tokens[lastTokenIndex].to <= span.from) {
+            lastTokenIndex = -1
+        }
+
+        // Handle edge cases
+        if (tokenFrom == -1) tokenFrom = 0
+        if (lastTokenIndex == -1) lastTokenIndex = tokens.size - 1
+
+        // tokenTo is exclusive: one past the last token
+        return span.copy(tokenFrom = tokenFrom, tokenTo = lastTokenIndex + 1)
+    }
+
+    /**
+     * The raw (unquoted) stream annotations a single foundry contributes to one
+     * token: morphological features, POS, lemma, UPOS, extra w-attribute layers,
+     * and the outgoing/ROOT dependency edge. Shared between [forEachStreamItem]
+     * and the tar merge path so both emit identical strings.
+     */
+    internal fun morphoAnnotationsForToken(
+        prefix: String?,
+        foundry: String,
+        morphoSpan: MorphoSpan,
+        token: Span,
+        index: Int,
+        offsetToIndex: Map<String, Int>
+    ): List<String> {
+        val tokenAnnotations = mutableListOf<String>()
+
+        if (prefix != null) {
+            // Morphological features (sorted)
+            if (morphoSpan.feats != null && morphoSpan.feats != "_") {
+                val features = mutableListOf<String>()
+                morphoSpan.feats!!.split("|").forEach { feat ->
+                    val parts = feat.split("=")
+                    if (parts.size == 2) {
+                        val key = parts[0].lowercase().escapeKrillValue()
+                        val value = parts[1].lowercase().escapeKrillValue()
+                        features.add("$prefix/m:$key:$value")
+                    }
+                }
+                features.sorted().forEach { tokenAnnotations.add(it) }
+            }
+
+            // POS (xpos) with optional byte encoding - sorted by descending probability
+            if (morphoSpan.xpos != null && morphoSpan.xpos != "_") {
+                val xposList = morphoSpan.xpos!!.split("|")
+                val miscList = if (morphoSpan.misc != null && morphoSpan.misc != "_") {
+                    morphoSpan.misc!!.split("|")
+                } else {
+                    emptyList()
+                }
+
+                // Sort by descending probability if probabilities are available
+                val sortedPairs = if (miscList.size == xposList.size &&
+                                     miscList.all { it.toDoubleOrNull() != null }) {
+                    xposList.mapIndexed { index, xpos ->
+                        val certainty = miscList[index].toDoubleOrNull() ?: 0.0
+                        Pair(xpos, certainty)
+                    }.sortedByDescending { it.second }
+                } else {
+                    // If probabilities don't match, keep original order
+                    xposList.mapIndexed { index, xpos ->
+                        val certainty = if (index < miscList.size) {
+                            miscList[index].toDoubleOrNull()
+                        } else {
+                            null
+                        }
+                        Pair(xpos, certainty)
+                    }
+                }
+
+                sortedPairs.forEach { (xpos, certainty) ->
+                    if (certainty != null && sortedPairs.size > 1) {
+                        val payload = kotlin.math.round(certainty * 255).toInt()
+                        tokenAnnotations.add("$prefix/p:${xpos.escapeKrillValue()}\$<b>129<b>$payload")
+                    } else {
+                        tokenAnnotations.add("$prefix/p:${xpos.escapeKrillValue()}")
+                    }
+                }
+            }
+
+            // Lemma - sorted by descending probability if probabilities are available
+            if (morphoSpan.lemma != null && morphoSpan.lemma != "_") {
+                val lemmaList = morphoSpan.lemma!!.split("|").distinct()
+                val miscList = if (morphoSpan.misc != null && morphoSpan.misc != "_") {
+                    morphoSpan.misc!!.split("|")
+                } else {
+                    emptyList()
+                }
+
+                // Extract probabilities from misc (exclude Offset= parts)
+                val probabilities = miscList.filter { !it.startsWith("Offset=") }
+                    .mapNotNull { it.toDoubleOrNull() }
+
+                val sortedLemmas = if (probabilities.size == lemmaList.size) {
+                    // Sort by descending probability
+                    lemmaList.mapIndexed { index, lemma ->
+                        val certainty = probabilities.getOrNull(index) ?: 0.0
+                        Pair(lemma, certainty)
+                    }.sortedByDescending { it.second }.map { it.first }
+                } else {
+                    // If probabilities don't match, keep original order
+                    lemmaList
+                }
+
+                sortedLemmas.forEach { lemma ->
+                    tokenAnnotations.add("$prefix/l:${lemma.escapeKrillValue()}")
+                }
+            }
+
+            // UPOS (skip for tree_tagger as it only has xpos)
+            if (morphoSpan.upos != null && morphoSpan.upos != "_" && foundry != "tree_tagger") {
+                tokenAnnotations.add("$prefix/u:${morphoSpan.upos!!.escapeKrillValue()}")
+            }
+
+            // Extra inline w-attribute layers (norm, orig, phon, trans),
+            // each emitted under its own key like pos (p:) and lemma (l:).
+            if (morphoSpan.norm != null && morphoSpan.norm != "_") {
+                morphoSpan.norm!!.split("|").forEach {
+                    tokenAnnotations.add("$prefix/norm:${it.escapeKrillValue()}")
+                }
+            }
+            if (morphoSpan.orig != null && morphoSpan.orig != "_") {
+                morphoSpan.orig!!.split("|").forEach {
+                    tokenAnnotations.add("$prefix/orig:${it.escapeKrillValue()}")
+                }
+            }
+            if (morphoSpan.phon != null && morphoSpan.phon != "_") {
+                morphoSpan.phon!!.split("|").forEach {
+                    tokenAnnotations.add("$prefix/phon:${it.escapeKrillValue()}")
+                }
+            }
+            if (morphoSpan.trans != null && morphoSpan.trans != "_") {
+                morphoSpan.trans!!.split("|").forEach {
+                    tokenAnnotations.add("$prefix/trans:${it.escapeKrillValue()}")
+                }
+            }
+        }
+
+        // Dependency relations
+        if (morphoSpan.head != null && morphoSpan.head != "_" && morphoSpan.deprel != null && morphoSpan.deprel != "_") {
+            // Head can be either an offset (e.g., "100-110") or a token index (e.g., "1")
+            val headStr = morphoSpan.head!!
+            val resolvedHeadIndex = resolveHeadIndex(headStr, offsetToIndex)
+
+            if (resolvedHeadIndex != null) {
+                // Regular dependency - outgoing edge to head
+                tokenAnnotations.add(">:$prefix/d:${morphoSpan.deprel!!.escapeKrillValue()}\$<b>32<i>$resolvedHeadIndex")
+            } else if (isRootHead(headStr)) {
+                // ROOT node - use incoming edge format with full span info
+                tokenAnnotations.add("<:$prefix/d:${morphoSpan.deprel!!.escapeKrillValue()}\$<b>34<i>${token.from}<i>${token.to}<i>$index<i>1")
+            }
+        }
+
+        return tokenAnnotations
+    }
+
     // Krill metadata field keys that were named misleadingly early on. By default we
     // emit the corrected names; the original names map to their proper meaning:
     //   textClass  -> dmozDomain (DMOZ-based topic-domain classification)
@@ -110,49 +386,49 @@
         "textDomain" to "idsColumn"
     )
 
-    fun generateTo(
-        out: Appendable,
+    /** Where a metadata field object originated. The Krill tar merge path uses this
+     *  to apply different replacement policies per origin. */
+    enum class FieldOrigin { SIGLE, HEADER, STANDOFF }
+
+    /** A ready-to-emit metadata field: its emitted key and complete JSON object. */
+    data class FieldEntry(val key: String, val json: String, val origin: FieldOrigin)
+
+    /**
+     * Build the metadata field objects for a text, in emission order (sigles, header
+     * fields, stand-off fields). Shared between [generateTo] and the Krill tar merge
+     * path so both produce identical field JSON.
+     */
+    fun buildMetadataFieldEntries(
         textData: KrillTextData,
-        corpusMetadata: Map<String, MutableMap<String, Any>>,
-        docMetadata: Map<String, MutableMap<String, Any>>,
-        includeNonWordTokens: Boolean,
+        corpusMetadata: Map<String, Map<String, Any>>,
+        docMetadata: Map<String, Map<String, Any>>,
         legacyFieldNames: Boolean = false
-    ) {
-        val sb = StringBuilder()
-        sb.append("{")
-
-        // @context, @type, and version
-        sb.append("\"@context\":\"http://korap.ids-mannheim.de/ns/koral/0.4/context.jsonld\",")
-        sb.append("\"@type\":\"koral:corpus\",")
-        sb.append("\"version\":\"0.4\",")
-
-        // fields (metadata)
-        sb.append("\"fields\":[")
-        val fields = mutableListOf<String>()
+    ): List<FieldEntry> {
+        val fields = mutableListOf<FieldEntry>()
 
         // Extract corpus, doc, and text sigle from textId (e.g., "WUD24_I0083.95367")
         // Convert underscores to slashes for proper format
         val textIdWithSlashes = textData.textId.replace("_", "/").replace(".", "/")
         val sigleParts = textIdWithSlashes.split("/")
         if (sigleParts.size >= 3) {
-            fields.add(jsonObject(listOf(
+            fields.add(FieldEntry("corpusSigle", jsonObject(listOf(
                 "value" to jsonString(sigleParts[0]),
                 "type" to jsonString("type:string"),
                 "@type" to jsonString("koral:field"),
                 "key" to jsonString("corpusSigle")
-            )))
-            fields.add(jsonObject(listOf(
+            )), FieldOrigin.SIGLE))
+            fields.add(FieldEntry("docSigle", jsonObject(listOf(
                 "@type" to jsonString("koral:field"),
                 "value" to jsonString("${sigleParts[0]}/${sigleParts[1]}"),
                 "type" to jsonString("type:string"),
                 "key" to jsonString("docSigle")
-            )))
-            fields.add(jsonObject(listOf(
+            )), FieldOrigin.SIGLE))
+            fields.add(FieldEntry("textSigle", jsonObject(listOf(
                 "@type" to jsonString("koral:field"),
                 "type" to jsonString("type:string"),
                 "value" to jsonString(textIdWithSlashes),
                 "key" to jsonString("textSigle")
-            )))
+            )), FieldOrigin.SIGLE))
         }
 
         val resolvedHeaderMetadata = resolveHeaderMetadata(
@@ -256,12 +532,12 @@
             }
 
             val outKey = if (legacyFieldNames) key else CORRECTED_FIELD_NAMES[key] ?: key
-            fields.add(jsonObject(listOf(
+            fields.add(FieldEntry(outKey, jsonObject(listOf(
                 "key" to jsonString(outKey),
                 "@type" to jsonString("koral:field"),
                 "value" to fieldValue,
                 "type" to jsonString(fieldType)
-            )))
+            )), FieldOrigin.HEADER))
         }
 
         // Stand-off metadata fields (already typed/selected upstream). Skip any key
@@ -275,15 +551,37 @@
                 is List<*> -> jsonArray(v.map { jsonString(it.toString()) })
                 else -> jsonString(v.toString())
             }
-            fields.add(jsonObject(listOf(
+            fields.add(FieldEntry(field.key, jsonObject(listOf(
                 "key" to jsonString(field.key),
                 "@type" to jsonString("koral:field"),
                 "value" to fieldValue,
                 "type" to jsonString(field.type)
-            )))
+            )), FieldOrigin.STANDOFF))
         }
 
-        sb.append(fields.joinToString(","))
+        return fields
+    }
+
+    fun generateTo(
+        out: Appendable,
+        textData: KrillTextData,
+        corpusMetadata: Map<String, MutableMap<String, Any>>,
+        docMetadata: Map<String, MutableMap<String, Any>>,
+        includeNonWordTokens: Boolean,
+        legacyFieldNames: Boolean = false
+    ) {
+        val sb = StringBuilder()
+        sb.append("{")
+
+        // @context, @type, and version
+        sb.append("\"@context\":\"http://korap.ids-mannheim.de/ns/koral/0.4/context.jsonld\",")
+        sb.append("\"@type\":\"koral:corpus\",")
+        sb.append("\"version\":\"0.4\",")
+
+        // fields (metadata)
+        sb.append("\"fields\":[")
+        sb.append(buildMetadataFieldEntries(textData, corpusMetadata, docMetadata, legacyFieldNames)
+            .joinToString(",") { it.json })
         sb.append("],")
 
         // data section
@@ -307,74 +605,10 @@
         // Collect layers by foundry type (checking what data actually exists)
         val foundryLayers = mutableMapOf<String, MutableSet<String>>()
         textData.morphoByFoundry.keys.sorted().forEach { foundry ->
-            val shortFoundry = when(foundry) {
-                "base" -> null
-                "tree_tagger" -> "tt"
-                "marmot-malt" -> "marmot"
-                else -> foundry
-            }
+            val shortFoundry = foundryPrefix(foundry)
             if (shortFoundry != null) {
-                val layers = foundryLayers.getOrPut(shortFoundry) { mutableSetOf() }
-                val morphoData = textData.morphoByFoundry[foundry]?.values
-
-                // Check if this foundry has dependency annotations
-                val hasDependencies = morphoData?.any {
-                    it.head != null && it.head != "_" && it.deprel != null && it.deprel != "_"
-                } ?: false
-
-                if (hasDependencies) {
-                    layers.add("d=rels")
-                }
-
-                // Check if this foundry has lemma annotations
-                val hasLemma = morphoData?.any {
-                    it.lemma != null && it.lemma != "_"
-                } ?: false
-                if (hasLemma) {
-                    layers.add("l=tokens")
-                }
-
-                // Check if this foundry has POS annotations (xpos or upos)
-                val hasPos = morphoData?.any {
-                    (it.xpos != null && it.xpos != "_") || (it.upos != null && it.upos != "_")
-                } ?: false
-                if (hasPos) {
-                    layers.add("p=tokens")
-                }
-
-                // Check if this foundry has morphological features
-                val hasFeatures = morphoData?.any {
-                    it.feats != null && it.feats != "_"
-                } ?: false
-                if (hasFeatures) {
-                    layers.add("m=tokens")
-                }
-
-                // Check if this foundry has UPOS (skip for tree_tagger)
-                if (foundry != "tree_tagger") {
-                    val hasUpos = morphoData?.any {
-                        it.upos != null && it.upos != "_"
-                    } ?: false
-                    if (hasUpos) {
-                        layers.add("u=tokens")
-                    }
-                }
-
-                // Extra inline w-attribute layers (norm, orig, phon, trans) are
-                // rare; a single short-circuiting scan gates the four per-attribute
-                // checks so corpora without them pay at most one extra pass.
-                val hasExtra = morphoData?.any {
-                    (it.norm != null && it.norm != "_") || (it.orig != null && it.orig != "_") ||
-                    (it.phon != null && it.phon != "_") || (it.trans != null && it.trans != "_")
-                } ?: false
-                if (hasExtra) {
-                    // hasExtra is only true when morphoData is non-null, so the
-                    // compiler smart-casts it here (no safe call needed).
-                    if (morphoData.any { it.norm != null && it.norm != "_" }) layers.add("norm=tokens")
-                    if (morphoData.any { it.orig != null && it.orig != "_" }) layers.add("orig=tokens")
-                    if (morphoData.any { it.phon != null && it.phon != "_" }) layers.add("phon=tokens")
-                    if (morphoData.any { it.trans != null && it.trans != "_" }) layers.add("trans=tokens")
-                }
+                foundryLayers.getOrPut(shortFoundry) { mutableSetOf() }
+                    .addAll(computeFoundryLayers(foundry, textData.morphoByFoundry[foundry]?.values))
             }
         }
 
@@ -523,12 +757,7 @@
             .map { (foundry, morphoSpans) ->
                 FoundryMorphoData(
                     foundry = foundry,
-                    prefix = when (foundry) {
-                        "tree_tagger" -> "tt"
-                        "marmot-malt" -> "marmot"
-                        "base" -> null
-                        else -> foundry
-                    },
+                    prefix = foundryPrefix(foundry),
                     morphoSpans = morphoSpans
                 )
             }
@@ -552,13 +781,8 @@
                     val prefix = foundryData.prefix ?: foundryData.foundry
 
                     // Check if this is a ROOT dependency (head == 0)
-                    if (!(headStr == "0" || (headStr.contains("-") && headStr.startsWith("0-")))) {
-                        val resolvedHeadIndex = if (headStr.contains("-")) {
-                            offsetToIndex[headStr]
-                        } else {
-                            val idx = headStr.toIntOrNull()
-                            if (idx != null && idx > 0) idx - 1 else null
-                        }
+                    if (!isRootHead(headStr)) {
+                        val resolvedHeadIndex = resolveHeadIndex(headStr, offsetToIndex)
 
                         if (resolvedHeadIndex != null) {
                             inverseDeps.getOrPut(resolvedHeadIndex) { mutableListOf() }
@@ -642,29 +866,7 @@
         // Resolve tokenFrom and tokenTo for structural spans
         // Note: tokenTo is exclusive (one past the last token index)
         val resolvedStructureSpans = allStructureSpans.map { span ->
-            if (span.tokenFrom >= 0 && span.tokenTo >= 0) {
-                // Already resolved
-                span
-            } else {
-                var tokenFrom = lowerBoundTokenFrom(tokens, span.from)
-                if (tokenFrom >= tokens.size || tokens[tokenFrom].from >= span.to) {
-                    tokenFrom = -1
-                }
-
-                var lastTokenIndex = upperBoundTokenTo(tokens, span.to) - 1
-                if (lastTokenIndex < 0 || tokens[lastTokenIndex].to <= span.from) {
-                    lastTokenIndex = -1
-                }
-
-                // Handle edge cases
-                if (tokenFrom == -1) tokenFrom = 0
-                if (lastTokenIndex == -1) lastTokenIndex = tokens.size - 1
-
-                // tokenTo is exclusive: one past the last token
-                val tokenTo = lastTokenIndex + 1
-
-                span.copy(tokenFrom = tokenFrom, tokenTo = tokenTo)
-            }
+            resolveStructureSpanTokenRange(span, tokens)
         }
 
         val resolvedSentenceFoundries = resolvedStructureSpans.foundriesWithSentenceSpans()
@@ -708,14 +910,7 @@
                 // Add all structural spans that start at token 0 or cover the whole document
                 val spansAtZero = spansByToken[0].orEmpty()
                 spansAtZero.forEach { span ->
-                    val spanAnnotation = if (span.attributes.isEmpty()) {
-                        "<>:${span.layer}\$<b>64<i>${span.from}<i>${span.to}<i>${span.tokenTo}<b>${span.depth}"
-                    } else {
-                        // Spans with attributes get a unique ID
-                        val attrId = span.depth
-                        "<>:${span.layer}\$<b>64<i>${span.from}<i>${span.to}<i>${span.tokenTo}<b>${span.depth}<s>$attrId"
-                    }
-                    tokenAnnotations.add(jsonString(spanAnnotation))
+                    tokenAnnotations.add(jsonString(structureSpanAnnotation(span)))
 
                     // Add attribute annotations
                     span.attributes.forEach { (key, value) ->
@@ -730,12 +925,7 @@
             } else {
                 // Add structural spans that start at this token
                 spansByToken[index]?.forEach { span ->
-                    val spanAnnotation = if (span.attributes.isEmpty()) {
-                        "<>:${span.layer}\$<b>64<i>${span.from}<i>${span.to}<i>${span.tokenTo}<b>${span.depth}"
-                    } else {
-                        "<>:${span.layer}\$<b>64<i>${span.from}<i>${span.to}<i>${span.tokenTo}<b>${span.depth}<s>${span.depth}"
-                    }
-                    tokenAnnotations.add(jsonString(spanAnnotation))
+                    tokenAnnotations.add(jsonString(structureSpanAnnotation(span)))
 
                     span.attributes.forEach { (key, value) ->
                         val attrAnnotation = if (value.isEmpty()) {
@@ -771,148 +961,16 @@
 
             // Add inverse dependency annotations (<:) for dependents pointing to this token as head
             inverseDeps[index]?.sortedBy { "${it.foundry}/${it.deprel}" }?.forEach { inv ->
-                tokenAnnotations.add(jsonString("<:${inv.foundry}/d:${inv.deprel.escapeKrillValue()}\$<b>32<i>${inv.dependentIndex}"))
+                tokenAnnotations.add(jsonString(inverseDependencyAnnotation(inv.foundry, inv.deprel, inv.dependentIndex)))
             }
 
             // Collect annotations from all foundries for this token
             sortedFoundries.forEach { foundryData ->
-                val foundry = foundryData.foundry
                 val morphoSpan = foundryData.morphoSpans[spanKey]
                 if (morphoSpan != null) {
-                    val prefix = foundryData.prefix
-
-                    if (prefix != null) {
-                        // Morphological features (sorted)
-                        if (morphoSpan.feats != null && morphoSpan.feats != "_") {
-                            val features = mutableListOf<String>()
-                            morphoSpan.feats!!.split("|").forEach { feat ->
-                                val parts = feat.split("=")
-                                if (parts.size == 2) {
-                                    val key = parts[0].lowercase().escapeKrillValue()
-                                    val value = parts[1].lowercase().escapeKrillValue()
-                                    features.add("$prefix/m:$key:$value")
-                                }
-                            }
-                            features.sorted().forEach { tokenAnnotations.add(jsonString(it)) }
-                        }
-
-                        // POS (xpos) with optional byte encoding - sorted by descending probability
-                        if (morphoSpan.xpos != null && morphoSpan.xpos != "_") {
-                            val xposList = morphoSpan.xpos!!.split("|")
-                            val miscList = if (morphoSpan.misc != null && morphoSpan.misc != "_") {
-                                morphoSpan.misc!!.split("|")
-                            } else {
-                                emptyList()
-                            }
-
-                            // Sort by descending probability if probabilities are available
-                            val sortedPairs = if (miscList.size == xposList.size && 
-                                                 miscList.all { it.toDoubleOrNull() != null }) {
-                                xposList.mapIndexed { index, xpos ->
-                                    val certainty = miscList[index].toDoubleOrNull() ?: 0.0
-                                    Pair(xpos, certainty)
-                                }.sortedByDescending { it.second }
-                            } else {
-                                // If probabilities don't match, keep original order
-                                xposList.mapIndexed { index, xpos ->
-                                    val certainty = if (index < miscList.size) {
-                                        miscList[index].toDoubleOrNull()
-                                    } else {
-                                        null
-                                    }
-                                    Pair(xpos, certainty)
-                                }
-                            }
-
-                            sortedPairs.forEach { (xpos, certainty) ->
-                                if (certainty != null && sortedPairs.size > 1) {
-                                    val payload = kotlin.math.round(certainty * 255).toInt()
-                                    tokenAnnotations.add(jsonString("$prefix/p:${xpos.escapeKrillValue()}\$<b>129<b>$payload"))
-                                } else {
-                                    tokenAnnotations.add(jsonString("$prefix/p:${xpos.escapeKrillValue()}"))
-                                }
-                            }
-                        }
-
-                        // Lemma - sorted by descending probability if probabilities are available
-                        if (morphoSpan.lemma != null && morphoSpan.lemma != "_") {
-                            val lemmaList = morphoSpan.lemma!!.split("|").distinct()
-                            val miscList = if (morphoSpan.misc != null && morphoSpan.misc != "_") {
-                                morphoSpan.misc!!.split("|")
-                            } else {
-                                emptyList()
-                            }
-                            
-                            // Extract probabilities from misc (exclude Offset= parts)
-                            val probabilities = miscList.filter { !it.startsWith("Offset=") }
-                                .mapNotNull { it.toDoubleOrNull() }
-                            
-                            val sortedLemmas = if (probabilities.size == lemmaList.size) {
-                                // Sort by descending probability
-                                lemmaList.mapIndexed { index, lemma ->
-                                    val certainty = probabilities.getOrNull(index) ?: 0.0
-                                    Pair(lemma, certainty)
-                                }.sortedByDescending { it.second }.map { it.first }
-                            } else {
-                                // If probabilities don't match, keep original order
-                                lemmaList
-                            }
-                            
-                            sortedLemmas.forEach { lemma ->
-                                tokenAnnotations.add(jsonString("$prefix/l:${lemma.escapeKrillValue()}"))
-                            }
-                        }
-
-                        // UPOS (skip for tree_tagger as it only has xpos)
-                        if (morphoSpan.upos != null && morphoSpan.upos != "_" && foundry != "tree_tagger") {
-                            tokenAnnotations.add(jsonString("$prefix/u:${morphoSpan.upos!!.escapeKrillValue()}"))
-                        }
-
-                        // Extra inline w-attribute layers (norm, orig, phon, trans),
-                        // each emitted under its own key like pos (p:) and lemma (l:).
-                        if (morphoSpan.norm != null && morphoSpan.norm != "_") {
-                            morphoSpan.norm!!.split("|").forEach {
-                                tokenAnnotations.add(jsonString("$prefix/norm:${it.escapeKrillValue()}"))
-                            }
-                        }
-                        if (morphoSpan.orig != null && morphoSpan.orig != "_") {
-                            morphoSpan.orig!!.split("|").forEach {
-                                tokenAnnotations.add(jsonString("$prefix/orig:${it.escapeKrillValue()}"))
-                            }
-                        }
-                        if (morphoSpan.phon != null && morphoSpan.phon != "_") {
-                            morphoSpan.phon!!.split("|").forEach {
-                                tokenAnnotations.add(jsonString("$prefix/phon:${it.escapeKrillValue()}"))
-                            }
-                        }
-                        if (morphoSpan.trans != null && morphoSpan.trans != "_") {
-                            morphoSpan.trans!!.split("|").forEach {
-                                tokenAnnotations.add(jsonString("$prefix/trans:${it.escapeKrillValue()}"))
-                            }
-                        }
-                    }
-
-                    // Dependency relations
-                    if (morphoSpan.head != null && morphoSpan.head != "_" && morphoSpan.deprel != null && morphoSpan.deprel != "_") {
-                        // Head can be either an offset (e.g., "100-110") or a token index (e.g., "1")
-                        val headStr = morphoSpan.head!!
-                        val resolvedHeadIndex = if (headStr.contains("-")) {
-                            // Offset format - resolve to token index
-                            offsetToIndex[headStr]
-                        } else {
-                            // Already a token index (1-based CoNLL-U format)
-                            val idx = headStr.toIntOrNull()
-                            if (idx != null && idx > 0) idx - 1 else null  // Convert 1-based to 0-based
-                        }
-
-                        if (resolvedHeadIndex != null) {
-                            // Regular dependency - outgoing edge to head
-                            tokenAnnotations.add(jsonString(">:$prefix/d:${morphoSpan.deprel!!.escapeKrillValue()}\$<b>32<i>$resolvedHeadIndex"))
-                        } else if (headStr == "0" || (headStr.contains("-") && headStr.startsWith("0-"))) {
-                            // ROOT node - use incoming edge format with full span info
-                            tokenAnnotations.add(jsonString("<:$prefix/d:${morphoSpan.deprel!!.escapeKrillValue()}\$<b>34<i>${token.from}<i>${token.to}<i>$index<i>1"))
-                        }
-                    }
+                    morphoAnnotationsForToken(
+                        foundryData.prefix, foundryData.foundry, morphoSpan, token, index, offsetToIndex
+                    ).forEach { tokenAnnotations.add(jsonString(it)) }
                 }
             }
 
@@ -1045,6 +1103,9 @@
 
     private fun jsonString(value: String): String = "\"${value.escapeJson()}\""
 
+    /** Quote and escape a stream annotation exactly like full generation does (for the merge path). */
+    internal fun quoteJson(value: String): String = jsonString(value)
+
     private fun jsonArray(items: List<String>): String = items.joinToString(",", "[", "]")
 
     private fun jsonObject(pairs: List<Pair<String, String>>): String {
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonPatcher.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonPatcher.kt
new file mode 100644
index 0000000..f437cf2
--- /dev/null
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/formatters/KrillJsonPatcher.kt
@@ -0,0 +1,626 @@
+package de.ids_mannheim.korapxmltools.formatters
+
+import de.ids_mannheim.korapxmltools.KorapXmlTool
+import java.util.SortedSet
+
+/**
+ * Surgical, lexical-level patching of existing Krill JSON documents, used when an
+ * existing Krill tar is given as input and should be updated from KorAP-XML ZIPs
+ * and/or stand-off metadata files ("merge mode").
+ *
+ * The patcher never re-serializes untouched parts of a document: it locates the
+ * regions to change with a small JSON scanner and splices replacement text in,
+ * so texts and annotations that are not affected by the update are preserved
+ * byte-for-byte. This keeps the merge robust for tars produced by older versions
+ * of this tool or by korapxml2krill (Perl).
+ */
+object KrillJsonPatcher {
+
+    /** How a new field is merged into the existing "fields" array. */
+    enum class FieldMode {
+        /** Replace the existing field with the same (or alias) key, else append. */
+        REPLACE_OR_APPEND,
+
+        /** Only append if no field with the same (or alias) key exists. */
+        APPEND_IF_MISSING
+    }
+
+    data class FieldPatch(val key: String, val json: String, val mode: FieldMode)
+
+    // Metadata keys that were renamed (see KrillJsonGenerator.CORRECTED_FIELD_NAMES).
+    // Replacing a field under one name must also remove its counterpart, so a tar
+    // written with legacy names never ends up carrying both variants.
+    private val FIELD_KEY_ALIASES = mapOf(
+        "textClass" to "dmozDomain", "dmozDomain" to "textClass",
+        "textDomain" to "idsColumn", "idsColumn" to "textDomain"
+    )
+
+    /**
+     * Merge [patches] into the top-level "fields" array of [json].
+     *
+     * Existing fields keep their position; a REPLACE_OR_APPEND patch replaces the
+     * first field whose key (or alias key) matches and removes later duplicates;
+     * patches without a match are appended at the end in the given order.
+     */
+    fun patchFields(json: String, patches: List<FieldPatch>): String {
+        if (patches.isEmpty()) return json
+        val fieldsRegion = findTopLevelMemberValue(json, "fields")
+            ?: throw IllegalArgumentException("No top-level \"fields\" array found in Krill JSON")
+        val elements = parseArrayElements(json, fieldsRegion)
+        val existingKeys = elements.map { extractMemberString(json, it, "key") }
+
+        // Resolve which existing element index each replacement patch targets.
+        val replacementByIndex = mutableMapOf<Int, FieldPatch>()
+        val dropIndices = mutableSetOf<Int>()
+        val toAppend = mutableListOf<FieldPatch>()
+        patches.forEach { patch ->
+            val targetKeys = setOf(patch.key, FIELD_KEY_ALIASES[patch.key] ?: patch.key)
+            val matches = existingKeys.withIndex().filter { (_, k) -> k != null && k in targetKeys }
+            when {
+                matches.isEmpty() -> toAppend.add(patch)
+
+                patch.mode == FieldMode.APPEND_IF_MISSING -> { /* exists: keep as is */ }
+
+                else -> {
+                    replacementByIndex[matches.first().index] = patch
+                    // Remove later duplicates and alias-named variants of the same field
+                    matches.drop(1).forEach { dropIndices.add(it.index) }
+                }
+            }
+        }
+        if (replacementByIndex.isEmpty() && dropIndices.isEmpty() && toAppend.isEmpty()) return json
+
+        val newArray = StringBuilder()
+        var first = true
+        elements.forEachIndexed { idx, range ->
+            if (idx in dropIndices) return@forEachIndexed
+            if (!first) newArray.append(',')
+            newArray.append(replacementByIndex[idx]?.json ?: json.substring(range.first, range.last + 1))
+            first = false
+        }
+        toAppend.forEach { patch ->
+            if (!first) newArray.append(',')
+            newArray.append(patch.json)
+            first = false
+        }
+
+        return json.substring(0, fieldsRegion.first + 1) + newArray +
+            json.substring(fieldsRegion.last)
+    }
+
+    /**
+     * Extract the value of the top-level "textSigle" field from the "fields" array,
+     * e.g. "REI/RBR/00473", or null if absent. Used by merge mode to recover the
+     * text id of a tar entry independent of its (lossily normalized) file name.
+     */
+    fun extractTextSigle(json: String): String? {
+        val fieldsRegion = findTopLevelMemberValue(json, "fields") ?: return null
+        parseArrayElements(json, fieldsRegion).forEach { el ->
+            if (extractMemberString(json, el, "key") == "textSigle") {
+                return extractMemberString(json, el, "value")
+            }
+        }
+        return null
+    }
+
+    // ------------------------------------------------------------------
+    // Foundry (token stream) patching
+    // ------------------------------------------------------------------
+
+    /**
+     * Replace or add annotation foundries in an existing Krill JSON document.
+     *
+     * [textData] carries the new annotations collected from KorAP-XML ZIP entries
+     * (morpho/dependency/sentences/constituency) for this text. Every foundry it
+     * contains is treated as authoritative: all existing stream annotations of
+     * that foundry are removed and the new ones inserted at the positions full
+     * generation would put them; layerInfos and foundries summaries are updated.
+     * Token offsets come from the existing stream, so the original base ZIP is
+     * not needed. Annotations whose offsets match no stream token (tokenization
+     * drift, filtered non-word tokens) are silently skipped, like in full
+     * generation.
+     */
+    fun patchFoundries(json: String, textData: KrillJsonGenerator.KrillTextData): String {
+        val foundries = (textData.morphoByFoundry.keys +
+            textData.sentencesCollectedByFoundry +
+            textData.constituencyCollectedByFoundry)
+            .filterNot { it == "base" || it == "dereko" }
+            .toSortedSet()
+        if (foundries.isEmpty()) return json
+
+        val dataRange = findTopLevelMemberValue(json, "data")
+            ?: throw IllegalArgumentException("No top-level \"data\" object found in Krill JSON")
+        val streamRange = findMemberValue(json, "stream", dataRange.first)
+            ?: throw IllegalArgumentException("No \"stream\" array found in Krill JSON data")
+        val layerInfosRange = findMemberValue(json, "layerInfos", dataRange.first)
+        val foundriesRange = findMemberValue(json, "foundries", dataRange.first)
+
+        // Parse the stream into per-token lists of raw (escaped, unquoted) annotation strings
+        val tokenArrays: MutableList<MutableList<String>> = parseArrayElements(json, streamRange).map { tokRange ->
+            parseArrayElements(json, tokRange).map { el ->
+                require(json[el.first] == '"') { "Non-string stream annotation at offset ${el.first}" }
+                json.substring(el.first + 1, el.last)
+            }.toMutableList()
+        }.toMutableList()
+
+        // Token offsets from the existing stream ("_<i>$<i>from<i>to")
+        val offsetRegex = Regex("""^_\d+\$<i>(\d+)<i>(\d+)$""")
+        val tokens = tokenArrays.mapIndexed { idx, anns ->
+            val m = anns.firstNotNullOfOrNull { offsetRegex.matchEntire(it) }
+                ?: throw IllegalArgumentException("Stream token $idx has no offset annotation")
+            KorapXmlTool.Span(m.groupValues[1].toInt(), m.groupValues[2].toInt())
+        }
+        val offsetToIndex = HashMap<String, Int>(tokens.size * 2)
+        tokens.forEachIndexed { index, t -> offsetToIndex["${t.from}-${t.to}"] = index }
+
+        var layerInfoTokens = layerInfosRange?.let {
+            unescapeJsonString(json.substring(it.first + 1, it.last)).split(" ").filter { t -> t.isNotEmpty() }
+        } ?: emptyList()
+        var foundriesTokens = foundriesRange?.let {
+            unescapeJsonString(json.substring(it.first + 1, it.last)).split(" ").filter { t -> t.isNotEmpty() }
+        } ?: emptyList()
+
+        foundries.forEach { foundry ->
+            val contribution = buildContribution(foundry, textData, tokens, offsetToIndex)
+            removeFoundryAnnotations(tokenArrays, contribution.names)
+            insertFoundryAnnotations(tokenArrays, contribution)
+            layerInfoTokens = rebuildLayerInfos(layerInfoTokens, contribution)
+            foundriesTokens = rebuildFoundries(foundriesTokens, contribution)
+        }
+
+        // Re-serialize the three patched regions, splicing right-to-left so offsets stay valid
+        val replacements = mutableListOf<Pair<IntRange, String>>()
+        replacements.add(streamRange to tokenArrays.joinToString(",", "[", "]") { anns ->
+            anns.joinToString(",", "[", "]") { "\"$it\"" }
+        })
+        layerInfosRange?.let { replacements.add(it to KrillJsonGenerator.quoteJson(layerInfoTokens.joinToString(" "))) }
+        foundriesRange?.let { replacements.add(it to KrillJsonGenerator.quoteJson(foundriesTokens.joinToString(" "))) }
+        replacements.sortByDescending { it.first.first }
+
+        val sb = StringBuilder(json)
+        replacements.forEach { (range, text) ->
+            sb.replace(range.first, range.last + 1, text)
+        }
+        return sb.toString()
+    }
+
+    /** Everything one foundry contributes to a text's stream and summary strings. */
+    private class FoundryContribution(
+        val foundry: String,
+        val prefix: String,
+        val fullName: String,
+        /** All name variants whose existing annotations must be removed. */
+        val names: Set<String>,
+        val sentenceCount: Int,
+        /** Resolved structural spans (sentences/constituency), keyed by start token. */
+        val spansByToken: Map<Int, List<KrillJsonGenerator.StructureSpan>>,
+        val hasConstituency: Boolean,
+        /** Inverse dependency annotations, keyed by head token: (sortKey, raw annotation). */
+        val inverseByToken: Map<Int, List<Pair<String, String>>>,
+        /** Per-token morpho/dependency block (raw annotation strings). */
+        val morphoByToken: Map<Int, List<String>>,
+        /** layerInfos descriptors like "p=tokens" for the morpho prefix. */
+        val morphoLayers: SortedSet<String>
+    )
+
+    private fun buildContribution(
+        foundry: String,
+        textData: KrillJsonGenerator.KrillTextData,
+        tokens: List<KorapXmlTool.Span>,
+        offsetToIndex: Map<String, Int>
+    ): FoundryContribution {
+        val prefix = KrillJsonGenerator.foundryPrefix(foundry) ?: foundry
+        val fullName = KrillJsonGenerator.foundryFullNameForPrefix(prefix)
+        val morphoSpans = textData.morphoByFoundry[foundry]
+
+        // Structural spans of this foundry (sentences "f/s:s", constituency "f/c:X")
+        val spans = textData.structureSpans
+            .filter { it.layer.startsWith("$foundry/") }
+            .map { KrillJsonGenerator.resolveStructureSpanTokenRange(it, tokens) }
+            .filter { it.tokenFrom >= 0 }
+        val spansByToken = spans.groupBy { it.tokenFrom }
+            .mapValues { (_, list) ->
+                list.sortedWith(compareByDescending<KrillJsonGenerator.StructureSpan> { it.depth }.thenBy { it.layer })
+            }
+        val sentenceCount = spans.count { it.layer == "$foundry/s:s" }
+        val hasConstituency = spans.any { it.layer.substringAfter('/').startsWith("c:") }
+
+        val morphoByToken = HashMap<Int, List<String>>()
+        val inverseByToken = HashMap<Int, MutableList<Pair<String, String>>>()
+        if (morphoSpans != null) {
+            tokens.forEachIndexed { index, token ->
+                val spanKey = "${token.from}-${token.to}"
+                val morphoSpan = morphoSpans[spanKey] ?: return@forEachIndexed
+                val anns = KrillJsonGenerator.morphoAnnotationsForToken(
+                    prefix, foundry, morphoSpan, token, index, offsetToIndex
+                )
+                if (anns.isNotEmpty()) {
+                    morphoByToken[index] = anns
+                }
+                // Inverse dependency edges pointing at this token's head
+                val headStr = morphoSpan.head
+                val deprel = morphoSpan.deprel
+                if (headStr != null && headStr != "_" && deprel != null && deprel != "_" &&
+                    !KrillJsonGenerator.isRootHead(headStr)
+                ) {
+                    val headIndex = KrillJsonGenerator.resolveHeadIndex(headStr, offsetToIndex)
+                    if (headIndex != null) {
+                        inverseByToken.getOrPut(headIndex) { mutableListOf() }
+                            .add("$prefix/$deprel" to KrillJsonGenerator.inverseDependencyAnnotation(prefix, deprel, index))
+                    }
+                }
+            }
+            inverseByToken.values.forEach { list -> list.sortBy { it.first } }
+        }
+
+        return FoundryContribution(
+            foundry = foundry,
+            prefix = prefix,
+            fullName = fullName,
+            names = setOf(foundry, prefix, fullName),
+            sentenceCount = sentenceCount,
+            spansByToken = spansByToken,
+            hasConstituency = hasConstituency,
+            inverseByToken = inverseByToken,
+            morphoByToken = morphoByToken,
+            morphoLayers = KrillJsonGenerator.computeFoundryLayers(foundry, morphoSpans?.values)
+        )
+    }
+
+    // Position classes of stream annotations, in the order full generation emits them
+    private const val CLS_COUNTS = 0     // "-:..." (token 0 only)
+    private const val CLS_SPANS = 1      // "<>:..." and their "@:..." attributes
+    private const val CLS_OFFSET = 2     // "_<i>$<i>f<i>t"
+    private const val CLS_LOWER = 3      // "i:..."
+    private const val CLS_NONWORD = 4    // "base/p:_"
+    private const val CLS_INVDEP = 5     // "<:X/d:...$<b>32<i>n"
+    private const val CLS_MORPHO = 6     // foundry blocks: "X/...", ">:X/...", root "<:...<b>34..."
+    private const val CLS_SURFACE = 7    // "s:..."
+
+    private fun classify(raw: String): Int = when {
+        raw.startsWith("-:") -> CLS_COUNTS
+        raw.startsWith("<>:") || raw.startsWith("@:") -> CLS_SPANS
+        raw.startsWith("_") -> CLS_OFFSET
+        raw.startsWith("i:") -> CLS_LOWER
+        raw == "base/p:_" -> CLS_NONWORD
+        raw.startsWith("<:") && raw.contains("\$<b>32") -> CLS_INVDEP
+        raw.startsWith("s:") -> CLS_SURFACE
+        else -> CLS_MORPHO
+    }
+
+    /** Foundry name variant an annotation belongs to, or null (base/structural/bookkeeping). */
+    private fun annotationOwner(raw: String): String? {
+        val body = when {
+            raw.startsWith("<>:") -> raw.substring(3)
+            raw.startsWith(">:") || raw.startsWith("-:") || raw.startsWith("@:") -> raw.substring(2)
+            raw.startsWith("<:") -> raw.substring(2)
+            else -> raw
+        }
+        val slash = body.indexOf('/')
+        if (slash <= 0) return null
+        return body.substring(0, slash)
+    }
+
+    private fun removeFoundryAnnotations(tokenArrays: MutableList<MutableList<String>>, names: Set<String>) {
+        tokenArrays.forEach { anns ->
+            anns.removeAll { raw ->
+                classify(raw) != CLS_NONWORD && annotationOwner(raw) in names
+            }
+        }
+    }
+
+    private fun insertFoundryAnnotations(
+        tokenArrays: MutableList<MutableList<String>>,
+        contribution: FoundryContribution
+    ) {
+        tokenArrays.forEachIndexed { index, anns ->
+            // Sentence count at token 0, among "-:X/sentences" sorted by foundry, before "-:tokens"
+            if (index == 0 && contribution.sentenceCount > 0) {
+                val countAnn = "-:${contribution.foundry}/sentences\$<i>${contribution.sentenceCount}"
+                var pos = 0
+                while (pos < anns.size && classify(anns[pos]) == CLS_COUNTS) {
+                    val raw = anns[pos]
+                    val owner = annotationOwner(raw)
+                    if (raw.startsWith("-:tokens") || (owner != null && owner != "base" && owner > contribution.foundry)) break
+                    pos++
+                }
+                anns.add(pos, escapeAnnotation(countAnn))
+            }
+
+            // Structural spans among "<>:" entries, ordered by (depth desc, layer)
+            contribution.spansByToken[index]?.forEach { span ->
+                val ann = KrillJsonGenerator.structureSpanAnnotation(span)
+                var pos = anns.indexOfFirst { classify(it) == CLS_SPANS }
+                if (pos < 0) {
+                    // No spans at this token yet: spans go right before the offset annotation
+                    pos = anns.indexOfFirst { classify(it) == CLS_OFFSET }
+                    if (pos < 0) pos = anns.size
+                } else {
+                    while (pos < anns.size && classify(anns[pos]) == CLS_SPANS) {
+                        val existing = parseSpanOrder(anns[pos])
+                        if (existing != null &&
+                            (existing.first < span.depth ||
+                                (existing.first == span.depth && existing.second > span.layer))
+                        ) break
+                        pos++
+                    }
+                }
+                anns.add(pos, escapeAnnotation(ann))
+            }
+
+            // Inverse dependency edges, sorted by "prefix/deprel" among existing <b>32 edges
+            contribution.inverseByToken[index]?.forEach { (sortKey, ann) ->
+                var pos = anns.indexOfFirst { classify(it) == CLS_INVDEP }
+                if (pos < 0) {
+                    // Zone is empty: it sits after i:/base/p:_ and before the morpho blocks
+                    pos = anns.indexOfFirst { classify(it) == CLS_MORPHO || classify(it) == CLS_SURFACE }
+                    if (pos < 0) pos = anns.size
+                } else {
+                    while (pos < anns.size && classify(anns[pos]) == CLS_INVDEP) {
+                        val existingKey = parseInverseDepKey(anns[pos])
+                        if (existingKey != null && existingKey > sortKey) break
+                        pos++
+                    }
+                }
+                anns.add(pos, escapeAnnotation(ann))
+            }
+
+            // The foundry's morpho/dependency block, between blocks sorted by foundry name
+            contribution.morphoByToken[index]?.let { block ->
+                var pos = -1
+                var i = 0
+                while (i < anns.size) {
+                    val cls = classify(anns[i])
+                    if (cls == CLS_SURFACE) {
+                        if (pos < 0) pos = i
+                        break
+                    }
+                    if (cls == CLS_MORPHO) {
+                        val owner = annotationOwner(anns[i])
+                        val ownerKey = owner?.let { foundrySortKey(it) }
+                        if (ownerKey != null && ownerKey > contribution.foundry) {
+                            pos = i
+                            break
+                        }
+                    }
+                    i++
+                }
+                if (pos < 0) pos = anns.size
+                anns.addAll(pos, block.map { escapeAnnotation(it) })
+            }
+        }
+    }
+
+    /** Sort key of a stream-annotation owner: map layer prefixes back to foundry names. */
+    private fun foundrySortKey(owner: String): String = when (owner) {
+        "tt", "treetagger" -> "tree_tagger"
+        else -> owner
+    }
+
+    /** (depth, layer) of an existing "<>:" span annotation, for ordered insertion. */
+    private fun parseSpanOrder(raw: String): Pair<Int, String>? {
+        val m = Regex("""^<>:([^$]+)\$<b>64(?:<i>-?\d+){3}<b>(\d+)""").find(raw) ?: return null
+        return m.groupValues[2].toInt() to m.groupValues[1]
+    }
+
+    /** "foundry/deprel" sort key of an existing inverse dependency annotation. */
+    private fun parseInverseDepKey(raw: String): String? {
+        val m = Regex("""^<:([^/]+)/d:([^$]*)\$""").find(raw) ?: return null
+        return "${m.groupValues[1]}/${m.groupValues[2]}"
+    }
+
+    /** JSON-escape a raw annotation exactly like the generator (content without quotes). */
+    private fun escapeAnnotation(ann: String): String {
+        val quoted = KrillJsonGenerator.quoteJson(ann)
+        return quoted.substring(1, quoted.length - 1)
+    }
+
+    private fun rebuildLayerInfos(existing: List<String>, c: FoundryContribution): List<String> {
+        val kept = existing.filterNot { it.substringBefore('/') in c.names }
+        val added = mutableListOf<String>()
+        if (c.sentenceCount > 0) added.add("${c.foundry}/s=spans")
+        if (c.hasConstituency) added.add("${c.foundry}/c=spans")
+        c.morphoLayers.forEach { added.add("${c.prefix}/$it") }
+        return (kept + added).sortedWith(compareBy({ layerInfoRank(it) }, { it.substringBefore('/') }, { it.substringAfter('/') }))
+    }
+
+    private fun layerInfoRank(token: String): Int = when {
+        token == "dereko/s=spans" -> 0
+        token == "base/p=tokens" -> 1
+        token.endsWith("/s=spans") -> 2
+        token.endsWith("/c=spans") -> 3
+        else -> 4
+    }
+
+    private fun rebuildFoundries(existing: List<String>, c: FoundryContribution): List<String> {
+        val kept = existing.filterNot { it.substringBefore('/') in c.names }
+
+        // Reconstruct the sets the generator derives its ordering from
+        val sentFoundries = kept.filter { it.endsWith("/sentences") }.map { it.substringBefore('/') }.toSortedSet()
+        val constitFoundries = kept.filter { it.endsWith("/structure") && it.substringBefore('/') != "dereko" }
+            .map { it.substringBefore('/') }.toSortedSet()
+        val annLayers = sortedMapOf<String, SortedSet<String>>()
+        kept.forEach {
+            val name = it.substringBefore('/')
+            val layer = it.substringAfter('/', "")
+            if (layer == "morpho" || layer == "dependency") {
+                annLayers.getOrPut(name) { sortedSetOf() }.add(layer)
+            }
+        }
+
+        if (c.sentenceCount > 0) sentFoundries.add(c.foundry)
+        if (c.hasConstituency) constitFoundries.add(c.foundry)
+        if (c.morphoLayers.isNotEmpty()) {
+            val layers = annLayers.getOrPut(c.fullName) { sortedSetOf() }
+            layers.clear()
+            if (c.morphoLayers.any { it == "d=rels" }) layers.add("dependency")
+            if (c.morphoLayers.any { it != "d=rels" }) layers.add("morpho")
+        }
+
+        val result = mutableListOf<String>()
+        // dereko block stays as-is (order is fixed)
+        kept.filter { it == "dereko" || it.startsWith("dereko/") }.forEach { result.add(it) }
+        // structure-advertised foundries: bare name, X/sentences, X/structure
+        (sentFoundries + constitFoundries).toSortedSet().forEach { f ->
+            if (!result.contains(f)) result.add(f)
+            if (f in sentFoundries) {
+                val e = "$f/sentences"
+                if (!result.contains(e)) result.add(e)
+            }
+            if (f in constitFoundries) {
+                val e = "$f/structure"
+                if (!result.contains(e)) result.add(e)
+            }
+        }
+        // annotation foundries, sorted like the generator (by layer prefix)
+        annLayers.keys.sortedBy { name -> if (name == "treetagger") "tt" else name }.forEach { name ->
+            result.add(name)
+            annLayers[name]!!.forEach { layer ->
+                val e = "$name/$layer"
+                if (!result.contains(e)) result.add(e)
+            }
+        }
+        return result
+    }
+
+    // ------------------------------------------------------------------
+    // Minimal JSON scanning utilities.
+    //
+    // These operate directly on the document string and return index ranges
+    // (inclusive first, inclusive last) so callers can splice text without
+    // re-serializing what they don't touch.
+    // ------------------------------------------------------------------
+
+    /** Index just past a JSON string that starts at [start] (which must be '"'). */
+    private fun skipString(s: String, start: Int): Int {
+        var i = start + 1
+        while (i < s.length) {
+            when (s[i]) {
+                '\\' -> i += 2
+                '"' -> return i + 1
+                else -> i++
+            }
+        }
+        throw IllegalArgumentException("Unterminated JSON string at offset $start")
+    }
+
+    /** Index just past the JSON value starting at [start] (skips leading whitespace). */
+    private fun skipValue(s: String, start: Int): Int {
+        var i = skipWhitespace(s, start)
+        return when (s[i]) {
+            '"' -> skipString(s, i)
+            '{', '[' -> {
+                val open = s[i]
+                val close = if (open == '{') '}' else ']'
+                var depth = 0
+                while (i < s.length) {
+                    when (s[i]) {
+                        '"' -> {
+                            i = skipString(s, i)
+                            continue
+                        }
+                        open -> depth++
+                        close -> {
+                            depth--
+                            if (depth == 0) return i + 1
+                        }
+                    }
+                    i++
+                }
+                throw IllegalArgumentException("Unbalanced JSON value at offset $start")
+            }
+            else -> {  // number, true, false, null
+                while (i < s.length && s[i] !in charArrayOf(',', '}', ']') && !s[i].isWhitespace()) i++
+                i
+            }
+        }
+    }
+
+    private fun skipWhitespace(s: String, start: Int): Int {
+        var i = start
+        while (i < s.length && s[i].isWhitespace()) i++
+        return i
+    }
+
+    /**
+     * Find the value of member [key] in the object starting at [objStart]
+     * (default: the root object). Returns the value's inclusive index range,
+     * or null if the key is not present at this object's top level.
+     */
+    fun findMemberValue(s: String, key: String, objStart: Int = 0): IntRange? {
+        var i = skipWhitespace(s, objStart)
+        require(i < s.length && s[i] == '{') { "Expected object at offset $objStart" }
+        i++
+        while (i < s.length) {
+            i = skipWhitespace(s, i)
+            if (s[i] == '}') return null
+            require(s[i] == '"') { "Expected member key at offset $i" }
+            val keyEnd = skipString(s, i)
+            val memberKey = unescapeJsonString(s.substring(i + 1, keyEnd - 1))
+            i = skipWhitespace(s, keyEnd)
+            require(s[i] == ':') { "Expected ':' at offset $i" }
+            i = skipWhitespace(s, i + 1)
+            val valueEnd = skipValue(s, i)
+            if (memberKey == key) return IntRange(i, valueEnd - 1)
+            i = skipWhitespace(s, valueEnd)
+            if (i < s.length && s[i] == ',') i++ else if (i < s.length && s[i] == '}') return null
+        }
+        return null
+    }
+
+    /** Find the value range of a member of the root object. */
+    fun findTopLevelMemberValue(s: String, key: String): IntRange? = findMemberValue(s, key, 0)
+
+    /** Inclusive ranges of the elements of the array spanning [arrayRange]. */
+    fun parseArrayElements(s: String, arrayRange: IntRange): List<IntRange> {
+        var i = skipWhitespace(s, arrayRange.first)
+        require(s[i] == '[') { "Expected array at offset ${arrayRange.first}" }
+        i = skipWhitespace(s, i + 1)
+        val elements = mutableListOf<IntRange>()
+        if (i <= arrayRange.last && s[i] == ']') return elements
+        while (i <= arrayRange.last) {
+            val end = skipValue(s, i)
+            elements.add(IntRange(skipWhitespace(s, i), end - 1))
+            i = skipWhitespace(s, end)
+            if (i > arrayRange.last || s[i] == ']') break
+            require(s[i] == ',') { "Expected ',' in array at offset $i" }
+            i = skipWhitespace(s, i + 1)
+        }
+        return elements
+    }
+
+    /** The string value of member [key] of the object at [objRange], unescaped; null if absent or not a string. */
+    fun extractMemberString(s: String, objRange: IntRange, key: String): String? {
+        val valueRange = findMemberValue(s, key, objRange.first) ?: return null
+        if (s[valueRange.first] != '"') return null
+        return unescapeJsonString(s.substring(valueRange.first + 1, valueRange.last))
+    }
+
+    fun unescapeJsonString(escaped: String): String {
+        if ('\\' !in escaped) return escaped
+        val sb = StringBuilder(escaped.length)
+        var i = 0
+        while (i < escaped.length) {
+            val c = escaped[i]
+            if (c != '\\') {
+                sb.append(c); i++; continue
+            }
+            i++
+            when (val e = escaped[i]) {
+                '"', '\\', '/' -> sb.append(e)
+                'b' -> sb.append('\b')
+                'f' -> sb.append('\u000C')
+                'n' -> sb.append('\n')
+                'r' -> sb.append('\r')
+                't' -> sb.append('\t')
+                'u' -> {
+                    sb.append(escaped.substring(i + 1, i + 5).toInt(16).toChar())
+                    i += 4
+                }
+                else -> throw IllegalArgumentException("Invalid JSON escape '\\$e'")
+            }
+            i++
+        }
+        return sb.toString()
+    }
+}
diff --git a/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KrillTarMergeTest.kt b/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KrillTarMergeTest.kt
new file mode 100644
index 0000000..22b561b
--- /dev/null
+++ b/app/src/test/kotlin/de/ids_mannheim/korapxmltools/KrillTarMergeTest.kt
@@ -0,0 +1,342 @@
+package de.ids_mannheim.korapxmltools
+
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
+import org.junit.After
+import org.junit.AfterClass
+import org.junit.Before
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.PrintStream
+import java.net.URL
+import java.util.zip.GZIPInputStream
+import kotlin.test.Test
+import kotlin.test.assertContains
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
+
+/**
+ * Tests for Krill tar merge mode: updating an existing Krill tar from
+ * KorAP-XML ZIPs and stand-off metadata files.
+ */
+class KrillTarMergeTest {
+
+    companion object {
+        private val tempDirs = mutableListOf<File>()
+
+        private fun newTempDir(key: String): File =
+            File.createTempFile(key, "").apply {
+                delete()
+                mkdirs()
+                tempDirs.add(this)
+            }
+
+        // Generated once and shared between tests (inputs are never modified)
+        private val baseTar: File by lazy { generateTar("merge_base", "rei_sample.krill.tar", resource("rei_sample.zip")) }
+        private val ttTar: File by lazy {
+            generateTar("merge_tt", "rei_sample.krill.tar", resource("rei_sample.zip"), resource("rei_sample.tree_tagger.zip"))
+        }
+
+        private fun resource(path: String): String {
+            val url: URL = Thread.currentThread().contextClassLoader.getResource(path)
+                ?: throw IllegalArgumentException("Resource $path not found")
+            return File(url.toURI()).path
+        }
+
+        private fun generateTar(key: String, tarName: String, vararg inputs: String): File {
+            val outputDir = newTempDir(key)
+            val exitCode = debug(arrayOf("-t", "krill", "-q", "-D", outputDir.path) + inputs)
+            assertEquals(0, exitCode, "Krill conversion should succeed for '$key'")
+            val tar = File(outputDir, tarName)
+            assertTrue(tar.exists(), "Expected $tarName for '$key'")
+            return tar
+        }
+
+        /** Raw (still compressed) tar entries by name, in order. */
+        private fun readTarEntries(tar: File): LinkedHashMap<String, ByteArray> {
+            val entries = LinkedHashMap<String, ByteArray>()
+            TarArchiveInputStream(tar.inputStream().buffered()).use { tarIn ->
+                var entry = tarIn.nextEntry
+                while (entry != null) {
+                    if (entry.isFile) {
+                        entries[entry.name] = tarIn.readAllBytes()
+                    }
+                    entry = tarIn.nextEntry
+                }
+            }
+            return entries
+        }
+
+        /** Decompressed JSON entries by name, in order. */
+        private fun readTarJson(tar: File): LinkedHashMap<String, String> {
+            val result = LinkedHashMap<String, String>()
+            readTarEntries(tar).forEach { (name, bytes) ->
+                if (name.endsWith(".json.gz")) {
+                    result[name] = GZIPInputStream(ByteArrayInputStream(bytes)).bufferedReader().use { it.readText() }
+                }
+            }
+            return result
+        }
+
+        @JvmStatic
+        @AfterClass
+        fun cleanupTempDirs() {
+            tempDirs.forEach { it.deleteRecursively() }
+            tempDirs.clear()
+        }
+    }
+
+    private val outContent = ByteArrayOutputStream(10000000)
+    private val errContent = ByteArrayOutputStream()
+    private val originalOut: PrintStream = System.out
+    private val originalErr: PrintStream = System.err
+
+    @Before
+    fun setUpStreams() {
+        System.setOut(PrintStream(outContent))
+        System.setErr(PrintStream(errContent))
+    }
+
+    @After
+    fun restoreStreams() {
+        System.setOut(originalOut)
+        System.setErr(originalErr)
+    }
+
+    private fun mergeTar(key: String, inputTar: File, vararg inputs: String): Pair<File, File> {
+        val outputDir = newTempDir(key)
+        val exitCode = debug(arrayOf("-t", "krill", "-q", "-D", outputDir.path, inputTar.path) + inputs)
+        assertEquals(0, exitCode, "Krill tar merge should succeed for '$key'")
+        val outputs = outputDir.listFiles { f -> f.name.endsWith(".tar") }.orEmpty()
+        assertEquals(1, outputs.size, "Expected exactly one merged tar for '$key'")
+        val log = File(outputs[0].path.replace(Regex("\\.tar$"), ".log"))
+        return outputs[0] to log
+    }
+
+    // ------------------------------------------------------------------
+    // Phase 1: metadata merge
+    // ------------------------------------------------------------------
+
+    @Test
+    fun mergedStandoffMetadataMatchesFullGeneration() {
+        val standoff = resource("rei_sample.domains.meta.xml")
+        val full = generateTar("standoff_full", "rei_sample.krill.tar", resource("rei_sample.zip"), standoff)
+        val (merged, _) = mergeTar("standoff_merge", baseTar, standoff)
+
+        val fullJson = readTarJson(full)
+        val mergedJson = readTarJson(merged)
+        // Full generation writes texts in compression-completion order, which is not
+        // deterministic; only the set of entries and their contents must match.
+        assertEquals(fullJson.keys, mergedJson.keys, "Entry names should match")
+        fullJson.forEach { (name, expected) ->
+            assertEquals(expected, mergedJson[name], "Merged JSON should equal full generation for $name")
+        }
+        assertContains(mergedJson.values.first(), "wikiDomain")
+    }
+
+    @Test
+    fun mergeLeavesUnaffectedTextsByteIdentical() {
+        // Stand-off metadata for a single text only
+        val standoffFile = File(newTempDir("standoff_partial_input"), "partial.meta.xml")
+        standoffFile.writeText(
+            """
+            <standOff xmlns="http://www.tei-c.org/ns/1.0">
+              <metadataLayer xml:id="testDomain" type="classification">
+                <taxonomy xml:id="testtaxonomy">
+                  <category xml:id="Politics"><catDesc>Politics</catDesc></category>
+                </taxonomy>
+                <textRef target="REI_RBR.00473">
+                  <catRef scheme="#testtaxonomy" target="#Politics" n="1" cert="0.9"/>
+                </textRef>
+              </metadataLayer>
+            </standOff>
+            """.trimIndent()
+        )
+        val (merged, _) = mergeTar("standoff_partial", baseTar, standoffFile.path)
+
+        val baseEntries = readTarEntries(baseTar)
+        val mergedEntries = readTarEntries(merged)
+        assertEquals(baseEntries.keys.toList(), mergedEntries.keys.toList())
+
+        baseEntries.forEach { (name, bytes) ->
+            if (name.startsWith("REI-RBR-00473")) {
+                assertFalse(bytes.contentEquals(mergedEntries[name]!!), "$name should have been patched")
+            } else {
+                assertTrue(bytes.contentEquals(mergedEntries[name]!!),
+                    "$name should be copied through byte-identically")
+            }
+        }
+        val patched = readTarJson(merged).getValue("REI-RBR-00473.json.gz")
+        assertContains(patched, "\"key\":\"testDomain\"")
+        assertContains(patched, "\"Politics\"")
+    }
+
+    @Test
+    fun mergeReplacesExistingStandoffField() {
+        // First give all texts wikiDomain fields, then merge an updated classification
+        // for one text and check it replaces (not duplicates) the old field.
+        val withDomains = generateTar(
+            "standoff_replace_base", "rei_sample.krill.tar",
+            resource("rei_sample.zip"), resource("rei_sample.domains.meta.xml")
+        )
+        val updateFile = File(newTempDir("standoff_replace_input"), "update.meta.xml")
+        updateFile.writeText(
+            """
+            <standOff xmlns="http://www.tei-c.org/ns/1.0">
+              <metadataLayer xml:id="wikiDomain" type="classification">
+                <taxonomy xml:id="wikitaxonomy">
+                  <category xml:id="UpdatedTopic"><catDesc>Updated topic</catDesc></category>
+                </taxonomy>
+                <textRef target="REI_RBR.00473">
+                  <catRef scheme="#wikitaxonomy" target="#UpdatedTopic" n="1" cert="0.99"/>
+                </textRef>
+              </metadataLayer>
+            </standOff>
+            """.trimIndent()
+        )
+        val (merged, _) = mergeTar("standoff_replace", withDomains, updateFile.path)
+        val patched = readTarJson(merged).getValue("REI-RBR-00473.json.gz")
+        assertContains(patched, "UpdatedTopic")
+        assertEquals(1, Regex("\"key\":\"wikiDomain\"").findAll(patched).count(),
+            "wikiDomain must be replaced, not duplicated")
+    }
+
+    @Test
+    fun mergeWarnsAndIgnoresTextsNotInTar() {
+        val wud24Tar = File(resource("wud24_sample.krill.tar"))
+        val (merged, log) = mergeTar("ignore_missing", wud24Tar, resource("rei_sample.tree_tagger.zip"))
+
+        // Nothing to patch: all entries must be byte-identical copies
+        val inEntries = readTarEntries(wud24Tar)
+        val outEntries = readTarEntries(merged)
+        assertEquals(inEntries.keys.toList(), outEntries.keys.toList())
+        inEntries.forEach { (name, bytes) ->
+            assertTrue(bytes.contentEquals(outEntries[name]!!), "$name should be unchanged")
+        }
+
+        assertTrue(log.exists(), "Merge log file should exist")
+        val logText = log.readText()
+        assertContains(logText, "Ignoring text REI_RBR.00473")
+        assertContains(logText, "not present in")
+    }
+
+    // ------------------------------------------------------------------
+    // Phase 2: annotation foundry merge
+    // ------------------------------------------------------------------
+
+    @Test
+    fun mergedTreeTaggerFoundryMatchesFullGeneration() {
+        val (merged, _) = mergeTar("tt_merge", baseTar, resource("rei_sample.tree_tagger.zip"))
+
+        val fullJson = readTarJson(ttTar)
+        val mergedJson = readTarJson(merged)
+        assertEquals(fullJson.keys, mergedJson.keys)
+        fullJson.forEach { (name, expected) ->
+            assertEquals(expected, mergedJson[name], "Merged JSON should equal full generation for $name")
+        }
+    }
+
+    @Test
+    fun mergedMaltDependenciesMatchFullGeneration() {
+        val full = generateTar(
+            "malt_full", "rei_sample.krill.tar",
+            resource("rei_sample.zip"), resource("rei_sample.malt.zip")
+        )
+        val (merged, _) = mergeTar("malt_merge", baseTar, resource("rei_sample.malt.zip"))
+
+        val fullJson = readTarJson(full)
+        val mergedJson = readTarJson(merged)
+        assertEquals(fullJson.keys, mergedJson.keys)
+        fullJson.forEach { (name, expected) ->
+            assertEquals(expected, mergedJson[name], "Merged JSON should equal full generation for $name")
+        }
+    }
+
+    @Test
+    fun mergedMultipleFoundriesMatchFullGeneration() {
+        val full = generateTar(
+            "multi_full", "rei_sample.krill.tar",
+            resource("rei_sample.zip"), resource("rei_sample.tree_tagger.zip"),
+            resource("rei_sample.malt.zip"), resource("rei_sample.opennlp.zip")
+        )
+        val (merged, _) = mergeTar(
+            "multi_merge", baseTar,
+            resource("rei_sample.tree_tagger.zip"), resource("rei_sample.malt.zip"),
+            resource("rei_sample.opennlp.zip")
+        )
+
+        val fullJson = readTarJson(full)
+        val mergedJson = readTarJson(merged)
+        assertEquals(fullJson.keys, mergedJson.keys)
+        fullJson.forEach { (name, expected) ->
+            assertEquals(expected, mergedJson[name], "Merged JSON should equal full generation for $name")
+        }
+    }
+
+    @Test
+    fun mergeReplacesExistingFoundry() {
+        // Re-merging the same tree_tagger annotations into a tar that already has
+        // them must be idempotent (replace, not duplicate).
+        val (merged, _) = mergeTar("tt_replace", ttTar, resource("rei_sample.tree_tagger.zip"))
+
+        val fullJson = readTarJson(ttTar)
+        val mergedJson = readTarJson(merged)
+        assertEquals(fullJson.keys, mergedJson.keys)
+        fullJson.forEach { (name, expected) ->
+            assertEquals(expected, mergedJson[name], "Replacing a foundry with itself must be idempotent for $name")
+        }
+    }
+
+    @Test
+    fun mergeSupportsLz4CompressedTars() {
+        val outputDir = newTempDir("lz4_base")
+        val exitCode = debug(arrayOf("-t", "krill", "-q", "--lz4", "-D", outputDir.path, resource("rei_sample.zip")))
+        assertEquals(0, exitCode)
+        val lz4Tar = File(outputDir, "rei_sample.krill.tar")
+        assertTrue(lz4Tar.exists())
+
+        val (merged, _) = mergeTar("lz4_merge", lz4Tar, resource("rei_sample.tree_tagger.zip"))
+        val entries = readTarEntries(merged)
+        assertTrue(entries.keys.all { it.endsWith(".json.lz4") }, "Entries should stay LZ4-compressed")
+        val json = net.jpountz.lz4.LZ4FrameInputStream(
+            ByteArrayInputStream(entries.getValue("REI-RBR-00473.json.lz4"))
+        ).bufferedReader().use { it.readText() }
+        assertContains(json, "tt/p:")
+        assertContains(json, "treetagger/morpho")
+    }
+
+    @Test
+    fun remergingHeadersFromBaseZipIsIdempotent() {
+        // The base ZIP carries the same headers the tar was built from, so re-merging
+        // it must leave every text's JSON unchanged (data/tokens/structure entries are
+        // ignored, header-derived fields regenerate to identical values).
+        val (merged, log) = mergeTar("header_remerge", baseTar, resource("rei_sample.zip"))
+
+        val baseJson = readTarJson(baseTar)
+        val mergedJson = readTarJson(merged)
+        assertEquals(baseJson.keys, mergedJson.keys)
+        baseJson.forEach { (name, expected) ->
+            assertEquals(expected, mergedJson[name], "Re-merging identical headers must not change $name")
+        }
+        assertContains(log.readText(), "cannot change the base tokenization")
+    }
+
+    // ------------------------------------------------------------------
+    // CLI semantics
+    // ------------------------------------------------------------------
+
+    @Test
+    fun mergeRejectsNonKrillOutputFormat() {
+        val exitCode = debug(arrayOf("-t", "conllu", baseTar.path, resource("rei_sample.tree_tagger.zip")))
+        assertNotEquals(0, exitCode, "Tar input without -t krill must be rejected")
+    }
+
+    @Test
+    fun mergeRequiresNewData() {
+        val outputDir = newTempDir("merge_no_data")
+        val exitCode = debug(arrayOf("-t", "krill", "-q", "-D", outputDir.path, baseTar.path))
+        assertNotEquals(0, exitCode, "Merging without any new input must be rejected")
+    }
+}
