hammer-upgrade: GC de generaciones huérfanas — 'hammer upgrade prune' (E4 hardening)

Tras un rollback las generaciones más nuevas quedan inalcanzables (no hay redo).
prune(state, keep) borra esas huérfanas (la cadena viva = current+ancestros vía
parent siempre se conserva); --keep N recorta además la profundidad de rollback.
live_chain() expuesto. 2 tests nuevos + paso prune en upgrade-e2e-test.sh (3->1
gens, árbol vivo intacto).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 21:49:18 -04:00
co-authored by Claude Opus 4.8
parent d23946fa3d
commit a22552e28f
4 changed files with 125 additions and 4 deletions
+12
View File
@@ -277,6 +277,13 @@ enum UpgradeCmd {
Rollback,
/// Muestra la generación viva y el historial.
Status,
/// Borra generaciones que el rollback ya no alcanza (huérfanas tras un rollback). Recupera espacio.
Prune {
/// Recorta también la cadena viva a sus N generaciones más nuevas (limita la profundidad de
/// rollback). Sin flag, conserva toda la cadena y borra sólo las huérfanas.
#[arg(long)]
keep: Option<usize>,
},
}
#[derive(Subcommand)]
@@ -871,6 +878,11 @@ fn main() -> anyhow::Result<()> {
println!(" {mark} {}{} ({} ficheros)", g.id, g.tree_dir, g.files.len());
}
}
UpgradeCmd::Prune { keep } => {
let r = hammer_upgrade::prune(&state_root, keep)?;
println!("✓ prune: {} borradas, {} conservadas", r.removed.len(), r.kept.len());
for id in &r.removed { println!(" - {id}"); }
}
}
}
}