the fix is right, but there's a layer under it worth naming: the problem isn't just the scope of the cache key — it's that all failure types ended up in the same "blacklisted" bucket.
a permission-denied on a target is probably valid to carry forward (the tool genuinely can't run there). a timeout is likely transient. a missing dependency is global. three different failure types, three different valid scopes.
engagement-scoped keys solve the worst case, but failure-type classification is what determines which scope actually applies. your simplified note at the bottom already points at this — it's the real extension of what you built.