fix: harden package post-processing provenance

Version package-owned output counts so unversioned global legacy values cannot remain authoritative after session load.

Capture extracted outputs through same-volume package staging, preserve overwrite, skip, and rename conflicts, retain partial abort output deterministically, and eliminate per-package full scans of shared roots while keeping extraction work parallel.

Carry normalized archive path provenance, prune explicitly deleted package generations without dropping package_done run evidence, and transfer run-owned post-process slots without releasing foreign waiters or exceeding maxParallelExtract.
This commit is contained in:
Sucukdeluxe
2026-08-22 13:02:27 +02:00
parent 7a052e995c
commit afa7da11da
8 changed files with 647 additions and 157 deletions
+39
View File
@@ -1200,6 +1200,7 @@ describe("settings storage", () => {
}],
remuxOperations: [],
outputCount: 1,
outputProvenanceVersion: 1,
outputProvenance: ["a".repeat(64), "invalid", "a".repeat(64)],
cleanupErrorCategory: "",
createdAt: 1_000,
@@ -1227,11 +1228,49 @@ describe("settings storage", () => {
archiveOperations: [expect.objectContaining({ id: "archive-1", durationMs: 4_000 })],
remuxOperations: [],
outputCount: 1,
outputProvenanceVersion: 1,
outputProvenance: ["a".repeat(64)],
cleanupErrorCategory: ""
}));
});
it("invalidates an unversioned legacy package output count on load", () => {
const normalized = normalizeLoadedSession({
version: 2,
packageOrder: ["legacy-output-count"],
packages: {
"legacy-output-count": {
id: "legacy-output-count",
name: "Legacy output count",
outputDir: "C:\\Downloads\\Legacy",
extractDir: "C:\\Downloads\\Shared",
status: "completed",
itemIds: [],
cancelled: false,
enabled: true,
outputCount: 48_000,
createdAt: 1_000,
updatedAt: 2_000
}
},
items: {},
runStartedAt: 0,
totalDownloadedBytes: 0,
summaryText: "",
reconnectUntil: 0,
reconnectReason: "",
paused: false,
running: false,
updatedAt: 2_000
});
expect(normalized.packages["legacy-output-count"]).toEqual(expect.objectContaining({
outputCount: 0,
outputProvenanceVersion: 1,
outputProvenance: []
}));
});
it("skips adding persisted history entries when history retention is never", () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-store-"));
tempDirs.push(dir);