feat(prune): R2 dry-run prune shell + persist wiring, report-only

Add ReaSamplerSession::pruneDryRun enumerating the resolved current bank
folder, feeding the R1 core, and returning a PruneReport (count/bytes/list).
New pure bankRelativeForName + buildPruneReport keep spelling and tally
testable. Register forever-stable BANK_PRUNE_FOLDER action, report-only. No deletion.
This commit is contained in:
2026-07-26 18:19:41 -04:00
parent 46176f3f04
commit c1473c42e1
10 changed files with 297 additions and 1 deletions
+25
View File
@@ -547,6 +547,29 @@ static void testHashWavContentDomainSeparationFromWholeFile() {
CHECK(contentHash != wholeHash);
}
// --- bankRelativeForName spelling consistency (Phase R, R2) -----------------
//
// The safety-critical property: the relative spelling the prune shell derives for an
// ENUMERATED folder entry (bankRelativeForName) must be byte-identical to the spelling
// the capture path stored in the index (deriveBankPaths().relativePath) for the same
// file name. A divergence here could make a referenced file look like an orphan.
static void testBankRelativeForNameMatchesDerivePathSpelling() {
// For a file the capture path created, deriveBankPaths produced relativePath;
// a directory listing yields the bare file name. bankRelativeForName(name) must
// reproduce the SAME string, or the pure core's exact-string match misfires.
const BankPaths p = deriveBankPaths("/proj", "kick", "001");
// p.fileName is the on-disk entry name a folder enumeration would return.
CHECK(bankRelativeForName(p.fileName) == p.relativePath);
}
static void testBankRelativeForNameConventionAndEdge() {
// The convention verbatim: "reasampler_bank/<name>" (the one place the spelling lives).
CHECK(bankRelativeForName("a.wav") == "reasampler_bank/a.wav");
// Empty in -> empty out (a defensive guard; a real enumeration never yields "").
CHECK(bankRelativeForName("").empty());
}
int main() {
testNormalizeSlashes();
testNormalizeSlashesCaseFolding();
@@ -585,6 +608,8 @@ int main() {
testHashWavContentEmptyFallsBackToHashBytes();
testHashWavContentListMetaSkipped();
testHashWavContentDomainSeparationFromWholeFile();
testBankRelativeForNameMatchesDerivePathSpelling();
testBankRelativeForNameConventionAndEdge();
if (g_fail == 0) std::printf("capture_paths: all tests passed\n");
else std::printf("capture_paths: %d CHECK(s) FAILED\n", g_fail);