diff --git a/scripts/agents/k2_ingested_merge_golden_smoke.sh b/scripts/agents/k2_ingested_merge_golden_smoke.sh
new file mode 100755
index 00000000..5d4883fa
--- /dev/null
+++ b/scripts/agents/k2_ingested_merge_golden_smoke.sh
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+# Merge neocities K2 Full fixture with golden mod-builds/KOTOR2_Full.toml for download URLs.
+set -euo pipefail
+
+ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
+cd "$ROOT"
+
+FIXTURE="${FIXTURE:-$ROOT/src/ModSync.Tests/Fixtures/k2_full_guide.md}"
+GOLDEN="${GOLDEN:-$ROOT/mod-builds/TOMLs/KOTOR2_Full.toml}"
+OUT_DIR="${OUT_DIR:-$ROOT/tmp/k2_merge_golden_smoke}"
+MERGED="${MERGED:-$OUT_DIR/k2_merged.toml}"
+KOTOR_DIR="${KOTOR_DIR:-$OUT_DIR/kotor}"
+MOD_DIR="${MOD_DIR:-$OUT_DIR/mods}"
+
+usage() {
+ cat <<'EOF'
+Usage: k2_ingested_merge_golden_smoke.sh [options]
+
+Merges the neocities K2 Full markdown fixture with golden KOTOR2_Full.toml
+(existing order; keep golden instructions, options, and download URLs).
+
+Options:
+ --fixture PATH Neocities markdown fixture (default: k2_full_guide.md)
+ --golden PATH Golden TOML (default: ./mod-builds/TOMLs/KOTOR2_Full.toml)
+ --out-dir PATH Output directory (default: ./tmp/k2_merge_golden_smoke)
+ -h, --help Show this help
+EOF
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --fixture) FIXTURE="$2"; shift 2 ;;
+ --golden) GOLDEN="$2"; shift 2 ;;
+ --out-dir) OUT_DIR="$2"; MERGED="$OUT_DIR/k2_merged.toml"; KOTOR_DIR="$OUT_DIR/kotor"; MOD_DIR="$OUT_DIR/mods"; shift 2 ;;
+ -h|--help) usage; exit 0 ;;
+ *) echo "Unknown option: $1" >&2; usage >&2; exit 1 ;;
+ esac
+done
+
+if [[ ! -f "$FIXTURE" ]]; then
+ echo "Fixture not found: $FIXTURE" >&2
+ exit 1
+fi
+
+if [[ ! -f "$GOLDEN" ]]; then
+ echo "Golden TOML not found: $GOLDEN" >&2
+ echo "Clone mod-builds: git clone https://github.com/th3w1zard1/mod-builds ./mod-builds" >&2
+ exit 1
+fi
+
+mkdir -p "$OUT_DIR"
+"$ROOT/scripts/agents/create_template_kotor_install.sh" "$KOTOR_DIR" "$MOD_DIR" >/dev/null
+
+dotnet build "$ROOT/src/ModSync.Tests/ModSync.Tests.csproj" -c Debug -f net9.0 -v q
+
+echo "==> merge (golden existing + neocities incoming)"
+dotnet run --project "$ROOT/src/ModSync.Tests/ModSync.Tests.csproj" -f net9.0 --no-build -- \
+ merge --existing "$GOLDEN" --incoming "$FIXTURE" \
+ --use-existing-order --prefer-existing-instructions --prefer-existing-options --prefer-existing-modlinks \
+ -f toml -o "$MERGED" --plaintext
+
+echo "==> validate --dry-run-only (structure + VFS; archives may be missing locally)"
+dotnet run --project "$ROOT/src/ModSync.Tests/ModSync.Tests.csproj" -f net9.0 --no-build -- \
+ validate --input "$MERGED" --game-dir "$KOTOR_DIR" --source-dir "$MOD_DIR" \
+ --dry-run-only --errors-only --best-effort || true
+
+echo "Merge smoke complete."
+echo " Merged TOML: $MERGED"
+echo " Next: stage/download mods, then install with --select mod:NAME"
diff --git a/src/ModSync.Tests/K2FullGuideMergeTests.cs b/src/ModSync.Tests/K2FullGuideMergeTests.cs
new file mode 100644
index 00000000..886b1160
--- /dev/null
+++ b/src/ModSync.Tests/K2FullGuideMergeTests.cs
@@ -0,0 +1,146 @@
+// Copyright 2021-2025 ModSync
+// Licensed under the Business Source License 1.1 (BSL 1.1).
+// See LICENSE.txt file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+using ModSync.Core;
+using ModSync.Core.CLI;
+using ModSync.Core.Services;
+
+using NUnit.Framework;
+
+namespace ModSync.Tests
+{
+ ///
+ /// Neocities K2 Full fixture merged with golden mod-builds/KOTOR2_Full.toml should
+ /// inherit download URLs and authored instructions for round-trip download workflows.
+ ///
+ [TestFixture]
+ public sealed class K2FullGuideMergeTests
+ {
+ private static readonly string GoldenTomlRelative = Path.Combine("mod-builds", "TOMLs", "KOTOR2_Full.toml");
+
+ private static string ResolveRepoRoot()
+ {
+ string[] candidates =
+ {
+ Path.GetFullPath(Path.Combine(TestContext.CurrentContext.TestDirectory, "..", "..", "..", "..")),
+ Path.GetFullPath(Path.Combine(TestContext.CurrentContext.TestDirectory, "..", "..", "..", "..", "..")),
+ Path.GetFullPath(Environment.CurrentDirectory),
+ };
+
+ foreach (string candidate in candidates.Distinct(StringComparer.Ordinal))
+ {
+ if (File.Exists(Path.Combine(candidate, "ModSync.sln")))
+ {
+ return candidate;
+ }
+ }
+
+ throw new DirectoryNotFoundException("Could not locate repository root containing ModSync.sln");
+ }
+
+ private static (string fixturePath, string goldenTomlPath) ResolveInputs()
+ {
+ string repoRoot = ResolveRepoRoot();
+ string fixturePath = Path.Combine(repoRoot, "src", "ModSync.Tests", "Fixtures", "k2_full_guide.md");
+ string goldenTomlPath = Path.Combine(repoRoot, GoldenTomlRelative);
+
+ if (!File.Exists(fixturePath))
+ {
+ Assert.Fail($"Expected neocities fixture at {fixturePath}");
+ }
+
+ if (!File.Exists(goldenTomlPath))
+ {
+ Assert.Ignore($"Golden TOML not found at {goldenTomlPath} (clone mod-builds at repo root for this test).");
+ }
+
+ return (fixturePath, goldenTomlPath);
+ }
+
+ private static List MergeNeocitiesWithGolden(string fixturePath, string goldenTomlPath)
+ {
+ var mergeOptions = new MergeOptions
+ {
+ UseExistingOrder = true,
+ PreferExistingInstructions = true,
+ PreferExistingOptions = true,
+ PreferExistingResourceRegistry = true,
+ };
+
+ return ComponentMergeService.MergeInstructionSets(
+ goldenTomlPath,
+ fixturePath,
+ mergeOptions);
+ }
+
+ [Test]
+ public void K2FullGuideFixture_MergeWithGoldenToml_InheritsDownloadUrls()
+ {
+ (string fixturePath, string goldenTomlPath) = ResolveInputs();
+
+ List merged = MergeNeocitiesWithGolden(fixturePath, goldenTomlPath);
+
+ Assert.That(merged.Count, Is.GreaterThanOrEqualTo(100),
+ "Merged set should retain the golden build component count");
+
+ ModComponent silentSion = merged.FirstOrDefault(c =>
+ c.Name.IndexOf("Silent Sion Restoration", StringComparison.OrdinalIgnoreCase) >= 0);
+ Assert.That(silentSion, Is.Not.Null, "Silent Sion should match between neocities fixture and golden TOML");
+
+ bool hasDownloadLink = silentSion.ResourceRegistry?.Count > 0;
+ Assert.That(hasDownloadLink, Is.True,
+ "Merged Silent Sion should keep golden download URLs in ResourceRegistry");
+
+ int withUrls = merged.Count(c => c.ResourceRegistry?.Count > 0);
+ Assert.That(withUrls, Is.GreaterThanOrEqualTo(100),
+ "Most golden K2 components should retain download URLs after neocities merge");
+ }
+
+ [Test]
+ public void K2FullGuideFixture_CliMergeWithGolden_ProducesMergedToml()
+ {
+ (string fixturePath, string goldenTomlPath) = ResolveInputs();
+
+ string outputToml = Path.Combine(Path.GetTempPath(), "ModSync_K2Merge_" + Guid.NewGuid() + ".toml");
+ try
+ {
+ int exit = ModBuildConverter.Run(new[]
+ {
+ "merge",
+ "--existing", goldenTomlPath,
+ "--incoming", fixturePath,
+ "--use-existing-order",
+ "--prefer-existing-instructions",
+ "--prefer-existing-options",
+ "--prefer-existing-modlinks",
+ "-f", "toml",
+ "-o", outputToml,
+ "--plaintext",
+ });
+
+ Assert.That(exit, Is.EqualTo(0), "CLI merge neocities fixture + golden TOML should succeed");
+ Assert.That(File.Exists(outputToml), Is.True);
+
+ List merged = FileLoadingService.LoadFromFile(outputToml).ToList();
+ ModComponent silentSion = merged.First(c =>
+ c.Name.IndexOf("Silent Sion Restoration", StringComparison.OrdinalIgnoreCase) >= 0);
+
+ Assert.That(silentSion.ResourceRegistry?.Count, Is.GreaterThan(0),
+ "CLI-merged Silent Sion should retain golden download metadata");
+ }
+ finally
+ {
+ if (File.Exists(outputToml))
+ {
+ File.Delete(outputToml);
+ }
+ }
+ }
+ }
+}