Log scratch-directory cleanup failures without replacing a successful
archive read or the original tool error. Keep scratch ownership in
execReadCommands and cover both outcomes for extraction and listing.
Keep execCommands as a plain executor that honors its cwd argument. Move
scratch-directory allocation and cleanup into a shared list/extract
helper, leaving archive creation on the caller-supplied directory.
Restore the existing helper layout and separate test cases rather than
bundling unrelated consolidation with the bug fix. Leave archive creation
unchanged and retain only the read isolation, necessary path handling,
and regression coverage.
Share the Windows BSD tar/zstd predicate and prepare archive and workspace
arguments once per command. Parameterize duplicate BSD-tar read tests and
use the real temporary-directory utilities in the concurrency fixture.
Retain the existing concurrency, path-handling, and failure coverage.
Run Windows BSD tar/zstd extraction and listing in private temporary
directories. Concurrent operations previously overwrote cache.tar in the
process working directory and could extract the wrong archive without
reporting an error. Debug listings during cache saves have the same race.
Resolve and quote archive and workspace paths before changing the child
working directory, and remove scratch files on success and failure.
Leave GNU tar, gzip, and the cache archive format unchanged.
Add deterministic regression tests for concurrent reads, relative paths
with spaces, and cleanup after failures in either subprocess.