M10: provenance populate + re-capture from source (bank-only)

Pure provenance core (recipe fingerprint, FX-chain identity, parent
detection) + shell reads; capture stamps provenance on resample-from-sample;
re-capture regenerates a provenanced sample from its source, never touching
the timeline. Adds BankIndex/BankBook in-place update. CTest-covered.
This commit is contained in:
2026-07-26 17:33:22 -04:00
parent 399dafa859
commit 20018c1df2
13 changed files with 1368 additions and 11 deletions
+30
View File
@@ -756,6 +756,35 @@ static void testRemoveAllBanksLatentScope() {
RemoveResult::RejectedSampleAbsent);
}
// M10: updateSampleInPlace refreshes a sample wherever it lives, order-preserving,
// no dedup, and reports no-op honestly for an absent id.
static void testUpdateSampleInPlace() {
BankBook book;
CHECK(book.createBank("drums", "Drums"));
CHECK(book.pool().index.add(sampleWith("kick")) == AddResult::Added);
CHECK(book.bank("drums")->index.add(sampleWith("snare")) == AddResult::Added);
CHECK(book.bank("drums")->index.add(sampleWith("hat")) == AddResult::Added);
// Refresh the middle entry of the NAMED bank: new path/hash, same id + slot.
Sample updated = sampleWith("snare");
updated.relativePath = "bank/snare-recaptured.wav";
updated.contentHash = "recaptured-hash";
CHECK(book.updateSampleInPlace("id-snare", updated));
CHECK(book.bank("drums")->index.all()[0].id == "id-snare"); // slot preserved
CHECK(book.bank("drums")->index.query("id-snare")->relativePath ==
"bank/snare-recaptured.wav");
CHECK(book.bank("drums")->index.size() == 2); // no new entry
// A sample in the POOL is found and updated too.
Sample pk = sampleWith("kick");
pk.contentHash = "kick-recaptured";
CHECK(book.updateSampleInPlace("id-kick", pk));
CHECK(book.pool().index.query("id-kick")->contentHash == "kick-recaptured");
// An absent id is an honest no-op.
CHECK(!book.updateSampleInPlace("id-nope", sampleWith("nope")));
}
int main() {
testPoolSeededAndDefaults();
testPoolPrivileges();
@@ -791,6 +820,7 @@ int main() {
testRemoveRejectionsNoMutation();
testHashReferencedElsewhere();
testRemoveAllBanksLatentScope();
testUpdateSampleInPlace();
if (g_fail == 0) std::printf("All tests passed.\n");
return g_fail ? 1 : 0;