Worktree erase purges everything it left on the node

Task 7230 · Done · Coder · created · updated

Operator ask (verbatim): "When worktree is erased everything must be purged from the node, including any bundles, caches, docker volumes, etc." ## Findings (from task 7221, measured on node shared-a1d14391) The co-located node's tree held 59 GB against its disk cap (default `vnode_disk_cap_gb` = 20 GB), so the Load column's D bar was pinned red: - `$JAAH_HOME/data/erase-rescue/`: 31 GB, made up of 176 git bundles of ~190 MB each written over Oct 14–18. `apps/jaahd/worktree_ops.py` (`worktree_erase`, around line 551) runs `git bundle create <f> --all` on every erase, BEFORE `_erase_signals` checks whether any work is at risk, so each erase stores the repo's full history. `rescue_bundle_retention_days` defaults to 90, so the bundles pile up at about 7 GB/day. - `tmp/`: 11 GB. This is per-slot Claude scratch dirs (`tmp/claude-<uid>/-…-repos-1-<N>`), `pytest-of-<user>/`, `cockpit-task-reports`, and so on, left behind after the slot's tree is gone. - `~/.local/share/docker`: 7.9 GB, made up of compose volumes and images of erased slots. - Caches (`~/.cache/ms-playwright*`, `~/.npm`) are shared across slots. ## Required 1. Erasing a worktree removes everything that slot left on the node: its rescue bundle(s), its docker compose project (containers, volumes, network, and slot-specific images), its tmp/scratch dirs (Claude scratchpad for that worktree path, pytest temp, task report/attachment dirs keyed to it), and any per-slot caches. 2. Rescue bundles do not outlive the erase. The current "bundle first, then refuse/force" flow (PRD R9, `rescue_sweep.py`, `node_rescue_bundles.py`, the `rescue_bundle_retention_days` knob, and the node page's bundle inventory) must be reconciled with this. Resolve the conflict explicitly and record the decision. The operator's ask governs: nothing persists after erase. If unpushed work is at risk, the erase is refused (the existing `_erase_signals` gate) rather than leaving a bundle behind. Remove whatever becomes dead (retention knob, sweep, inventory UI) per delete-don't-archive. 3. A one-time cleanup of existing orphans: bundles, and tmp/docker leftovers of slots that no longer exist, swept by the node daemon. Each node does this itself; no manual SSH. 4. Shared caches that serve live slots (npm, playwright browsers) are not deleted while another slot uses them. Bound their growth instead, or name why they stay. Out of scope: changing disk caps or thresholds, the D-bar UI, and anything outside the node daemon's erase/sweep path except what removing the rescue-bundle feature requires. Done means: - A test erases a slot that has a running compose stack, scratch/tmp dirs and (previously) a rescue bundle. Afterwards none of them remain on disk, and `docker volume ls` shows none of the slot's volumes. - An erase of a tree with unpushed commits is refused (no bundle written, tree left intact). - On a real node after deploy, `du -sh $JAAH_HOME/data/erase-rescue` is empty or the directory is gone, and the node's D bar drops accordingly. Cite the before and after figures. - `./dc check quick` is green.

Outcome

Erase now purges tree, stack (volumes/images/network), scratch and rescue dir, never refuses (operator order); rescue bundles deleted; hourly residue sweep. #5909+#5920 merged, quick green. Node: erase-rescue 36G→gone, home 70→36G. Drafts #7285 #7286 #7310.

Pull request Pull request

Artifacts

Activity

  • Created
  • Run
  • Runner started
  • Runner ended (done)