fix(pS-usage): close delete-ward residuals — remint on corrupt, named abort keys, truncation protect-all, abort->protect-all set

This commit is contained in:
2026-07-28 13:54:10 -04:00
parent a4aeb9dcc8
commit ec83f14738
8 changed files with 197 additions and 36 deletions
+6 -1
View File
@@ -317,6 +317,7 @@ struct PruneScan {
std::vector<std::string> orphans;
std::unordered_map<std::string, std::uint64_t> sizeByRel;
bool abortedUnreadableUsage = false;
std::vector<std::string> offendingUsageKeys; // non-empty iff abortedUnreadableUsage
};
// Non-throwing: readActiveProject + resolveBankFile are pure/string; every filesystem
@@ -381,8 +382,10 @@ PruneScan scanPruneOrphans(const BankBook& book, const OwnedFileManifest& owned)
// FAIL-SAFE ABORT: a present rsusage_* record could not be read/decoded, so the
// protected set is unknowable. Compute NO orphans — every downstream consumer
// (dry-run report, confirm set, fresh-recompute delete plan) then deletes
// nothing. The flag surfaces the reason to the action's console message.
// nothing. The flag + key names surface the reason so the action can name each
// offending key for operator recovery.
scan.abortedUnreadableUsage = true;
scan.offendingUsageKeys = usage.offendingKeys;
return scan;
}
scan.orphans = pruneOrphans(
@@ -402,7 +405,9 @@ PruneReport ReaSamplerSession::pruneDryRun() const {
// pS-usage fail-safe: surface the unreadable-record abort so the action halts with
// an explicit message instead of reporting "no orphaned files" (the count IS zero —
// the scan computed nothing — but the user must know the prune refused to run).
// The offending key names propagate so the action can name each one for recovery.
report.abortedUnreadableUsage = scan.abortedUnreadableUsage;
report.offendingUsageKeys = scan.offendingUsageKeys;
return report;
}