Localizing $CPAN::Distrostatus::something_has_failed_at seems to decouple calls to install() when I don't want them to know about each other, and halt_on_failure still works as far as I can tell:
DISTRO: foreach my $distro ( @distros ) { local $CPAN::Distrostatus::something_has_failed_at; say "Processing $distro..."; my $module = CPAN::Shell->expand( 'Module', $distro ) or die "CPAN.pm doesn't know about $distro!\n"; say "Installing $distro"; CPAN::Shell->install( $distro ); say "Finished processing $distro\n"; } I don't particularly like that as a permanent solution, but it's a fine one until the holidays are over. I think there's room for improvement in Distrostatus, but I'll think about that later and maybe finish my half a patch.