Skip to content

Name the sources in --purge's leaving list #461

Closed

Description

@blooop

Work

Name the sources in --purge's "Leaving N workspace(s)" list, and say what removing the cache costs the survivors.

The smallest high-value change on this map, and #452 argued why it is worth its own ticket: principle 2 is satisfied far more cheaply by the user can see it and decide than by reclaiming anything, and this is the one screen where somebody is actually deciding.

Two changes:

  • The leaving list prints workspace ids and never sources. A user looking at pythontemplate and my-hand-made-workspace cannot tell which is a dl <path> workspace whose clone is theirs and which is a hand-made one. Print the source beside the id.
  • Add a sentence that removing the cache drops what devlaunch knew about the survivors. This matters more after #456: the per-workspace markers live in the cache, so a purge that leaves foreign workspaces standing also destroys the records naming their volumes, and their volumes then become exactly the orphans Orphaned volumes with no surviving record #451 declined to reclaim.

Cost, already scoped: one golden in rust/dl/tests/lifecycle.rs and a paragraph in docs/cleanup.md. No em or en dashes in docs/ (test_docs_prose.py).

Deliberately not in scope: the dl --ls degradation under a moved repos_dir, which waits on whether repos_dir is supported at all.

Activity

  1. blooop commented on Aug 25, 2026

    @blooop
    OwnerAuthor

    breadcrumb: unblocked by #460, and smaller than when it was filed.

    The dl --ls degradation this ticket deferred needs no build work at all. repos_dir is being retired (#467), which makes is_devlaunch_clone's containment test complete, so the devlaunch:false / SIZE - / unsaved:null case stops being a bug to fix and becomes unrepresentable. Re-blocked on that ticket rather than on the decision, so the ordering is explicit.

    What remains is the original first half only, and one of its three examples goes with the retired key: print the source beside the id in the leaving list, and add the sentence about what removing the cache costs the survivors. That second half matters more after #456, since the per-workspace markers live in the cache.

  2. blooop commented on Aug 25, 2026

    @blooop
    OwnerAuthor

    breadcrumb: scope note and a second blocker, both from #459.

    The purge figure folds into this ticket. It is the same golden (PURGE_PLAN, rust/dl/tests/lifecycle.rs:751) and the same docs/cleanup.md paragraph as the leaving-list change already here, so two PRs over one prompt would be waste.

    How it must be computed, because the obvious route is wrong. Not by reusing prune_plan: that weighs only clones it removes and only worktrees inside clones it keeps, and purge's set is the union of both exclusions. It is a walk over <cache_dir>/repos — cache_dir, per R1, never the retired repos_dir — under run_if_lock_free, because prune_plan's per-repo lock is an unbounded wait while purge_all_data takes no lock at all, so a blocking report would be stricter than the deletion it precedes. And the figure is not a usize: 0 would mean both "nothing at risk" and "could not weigh", which is devlaunch#171's shipped bug one level up.

    Blocked on #446 as well as #467, because the count is only worth printing once the clone-level guard can see nested agent worktrees. Today it cannot, and a figure derived from the blind probe would read "0" over 104.5 GB of unsaved work, which is worse than printing nothing.

    If that reach does not land, the escape hatch from #459 applies instead: print no count, and make the current position explicit in docs/cleanup.md and #455's row as "the confirmation, and nothing else", with the reason beside it.

  3. blooop commented on Aug 25, 2026

    @blooop
    OwnerAuthor

    breadcrumb: unblocked by #467 (PR #481), and the review there handed this ticket a concrete case it must cover rather than a general aspiration.

    Reproduced: seed a devpod workspace whose localFolder is <retired repos_dir>/blooop/devlaunch/devlaunch-main-3j1t, which is exactly what a pre-#467 dl left on any machine that set the key. dl --purge -y prints

    Leaving 1 workspace(s) devlaunch did not create:
      - devlaunch-main-3j1t
    

    an opaque id with no path, while the same run deletes the metadata.json record that last pointed at the tree. commands.rs:801 never opens dl's records, so #467's migration notice does not fire on this path either. It is not permanent silence, since the notice returns on the next records-opening command while the key remains, but --purge is the one command whose promise is nothing left, and this is a tree it neither removes nor names.

    Two things this ticket now owns, then: naming the source beside each left workspace (its original scope), and deciding whether the retired-key notice belongs on the purge path. #467 deliberately left the second alone because printing it there means editing what a purge says about what it leaves, which is this ticket's surface.

    Also from #467: this ticket's first bullet loses the clause "which is devlaunch's own under a moved repos_dir", since a configuration can no longer place a clone anywhere. The stranded-by-a-prior-build case above replaces it, and is narrower and real.

  4. blooop commented on Aug 29, 2026

    @blooop
    OwnerAuthor

    Claimed 2026-08-29: build in progress from an interactive session (agent in an isolated worktree), managed by session devlaunch-2b as part of closing out map #444. PR to follow. If you are another session looking at this ticket, pick a different one.

  5. blooop commented on Aug 29, 2026

    @blooop
    OwnerAuthor

    breadcrumb: built in #515.

    Both halves of the remaining scope, plus the decision #467 handed over.

    • The source beside the id, from describe_source -- the same reading dl --ls's SOURCE column uses, so the two surfaces cannot describe one workspace differently. The unreadable-source arm is printed as devpod's object and said to be one, rather than sitting after a colon looking like a path.
    • What the cache costs the survivors, in two sentences under the list: they keep working, and a clone an older dl placed outside the cache is named only by a record inside it, so dl <ws> rm afterwards takes the workspace and leaves the tree. Not a claim about volumes, because those names are read from workspace_result.json under DEVPOD_HOME, which a purge does not touch. The doc comment on the constant is where Keep devlaunch's own copy of the volume names, and reclaim from it #456 will change that sentence.
    • The retired-key notice does belong on this path, answered yes. It reads config.toml directly rather than opening dl's records: opening them runs the cache migration, which would write records into the tree the command is about to remove and into one an aborted purge was asked to leave alone. Where a workspace still opens such a clone the list names the path; where none does, the notice is the only mention that tree gets.

    #481's reproduced case is a fixture (--stranded-clone) and a test: the plan names the path, the notice is on stderr, and after -y the tree is still standing while its record is gone, which is what the new sentences warn about.

    Not in scope and not attempted: the purge figure from #459, still blocked on #446.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions