Skip to content

afx cleanup: '[ok] cleaned up' when only deregistered — worktree-preservation is inconsistent and the message misrepresents it #1363

Description

@waleedkadous

Problem

afx cleanup -p <id> prints [ok] Builder <id> cleaned up! in two very different situations:

  1. Full cleanup — registry row removed, worktree removed, branch deleted.
  2. Deregistration only — registry row removed, but the worktree and branch are preserved on disk (with [info] Worktree preserved at: ... lines above the [ok]).

The [ok] cleaned up! reads as case 1 either way. An operator (or agent) scanning outcomes sees success and later finds .builders/ still populated — and by then the registry row is gone, so afx cleanup can no longer address the leftover at all ("Builder not found", the #1102 row-less gap). The tool's own preservation path manufactures row-less worktrees.

Observed inconsistency (two workspaces, 2026-08-02/06)

  • This repo's sweep: builders with tracked modifications (e.g. a modified package-lock.json) were preserved; builders with untracked-only dirt (builder artifacts, porch state) were fully removed — both printed [ok] cleaned up!. Neither the criterion nor the outcome difference is stated in the output.
  • A sibling workspace reports the same shape: two builders deregistered-but-preserved (one was checked out on a non-canonical branch, which may be a second preservation trigger; the other was on its canonical builder branch), a third under near-identical conditions fully removed. Same [ok] for all three.

Asks

  1. Honest messaging: when preserving, say [warn] Deregistered only — worktree preserved (uncommitted changes / non-canonical branch): <path> and exit distinctly, so scripts and agents can branch on it.
  2. Document (or make configurable) the preservation criteria — tracked-dirt vs untracked-dirt vs branch-mismatch is currently reverse-engineered folklore.
  3. Reachability after preservation: preserved worktrees should remain addressable by a cleanup form (ties into afx cleanup: no row-less teardown path + '-i <issue>' never matches bugfix builders (issue_number TEXT vs number ===) #1102's row-less teardown path) rather than requiring manual git worktree remove.

Related: #1102 (row-less teardown + -i bugfix matching), #1101 (SPLIT states).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/towerArea: Tower server / agent farm CLI

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions