Skip to main content

fold_orphaned_worktrees

Function fold_orphaned_worktrees 

Source
pub async fn fold_orphaned_worktrees(
    runs: &Path,
    worktrees_root: &Path,
    home: &Path,
    grace_secs: u64,
    now: Timestamp,
) -> usize
Expand description

Reclaim worktrees under worktrees_root that no run record in runs claims anymore, and return how many were removed.

fold_due only ever sees a worktree by walking runs/ first, so a worktree whose run record is already gone — magi run rm, or a record deleted before its worktree — never enters that loop at all: nothing there is looking for it. This walks the worktree bay directly instead, and removes any <short> directory that no run id maps to.

Two things must never happen, and this checks both before ever touching a directory:

  • A worktree bay is never the only kind of thing under worktrees_root, and this must not assume it is. A hand-placed scratch directory, or anything else an operator or another tool left in the same bay, has the same “no run claims it” shape as a genuine orphan but is not one - [looks_like_a_worktree_bay] is the same tag shape crate::run::is_run_id already requires of a real run’s short id, and anything else is left alone regardless of what else is true about it.
  • A worktree that was only just created might not have a run.json yet for a reason that has nothing to do with being orphaned. Runner::start and Runner::review both create the worktree before the first RunState::save lands, and that gap - several git subprocesses wide - is invisible to crate::daemon::is_working_on_short whenever the run is not being driven through this daemon’s own poll loop at all (a magi review invocation, for one). A directory whose own modification time is within grace_secs of now is left alone on that basis alone, the same margin fold_due gives a run before treating it as truly finished - long enough that no realistic gap between a worktree add and its run.json could ever be mistaken for one.

The one failure this must never cause is deleting the worktree of a run that is genuinely in flight. crate::daemon::is_working_on_short is the same liveness check fold_due trusts everywhere else in this module, checked by short id because there is no full id to compare here; when it cannot tell, this leaves the directory alone. Best-effort like the rest of housekeeping: one directory git or the filesystem refuses to give up is a tracing::warn, not a reason to abandon the rest of the pass.