Skip to content

[Feature]: decide and execute cleanup interactively #101

Description

@FeathBow

Problem or use case

Someone whose quota is full opens degu to free space. Today that takes three separate understandings before anything is freed.

Staging does not free quota. A confirmed degu clean moves findings into the staging trash, and README.md says plainly that staged data "still counts against quota until purged". So the obvious first command leaves the number that prompted the whole exercise unchanged. Space comes back from degu trash purge, from --purge, or from waiting out the seven-day expiry — a second step the person has to know exists.

The review tier is where the space usually is, and it is the hardest to act on. On an ML node the reclaimable gigabytes are model and compile caches, which are regenerable but costly, so degu correctly refuses to decide and leaves the judgement to the user. Expressing that judgement is the friction. --include-review takes every review finding at once. --review PATH takes exactly one, and scan prints that command only for the largest location. A policy is expressible — --include-review --min-size 5G --older-than 180 composes, and for scheduled cleanup that is the right shape — but a judgement that a rule cannot capture ("this model is coming back next week, that one is not") has to be recorded by transcribing paths out of a report that has already scrolled past.

Permanent removal is all or nothing. degu trash purge removes every entry; it has no --path. So a person who wants back the eight gigabytes sitting in one staged model directory, while keeping last week's other entries in reach of degu undo, cannot say that. The options are everything or patience.

None of these is a missing capability in the safety model — the tiers, the staging, the undo window and the confirmations are all doing their job. What is missing is a place to make the decisions they exist to protect.

Desired behavior

degu tui: an interactive surface for the decisions the printed report can only describe.

It presents the current scan and the current staging trash together, because that is where quota actually sits, and lets the reader decide per location:

  • which Needs review findings join this clean,
  • which staged entries are permanently removed now rather than left for undo or expiry.

It then previews the whole outcome — what will be staged, what will be permanently destroyed, what the trash will hold afterwards — and executes on confirmation. No command is typed to make it happen.

It is a wrapper over the CLI, structurally and not just in spirit. What the interface produces is the same argument set a person could have typed, handed to the same command implementation. It holds no scanning, admission, staging or deletion code of its own, so there is exactly one deletion path and no way to grow a second. The equivalent command line is shown before confirmation — not as something to type, but so that the next time the decision is a rule rather than a judgement, the reader already knows how to say it.

Three properties must not soften because the surface is graphical:

  • Not managed is never selectable, and Needs review is still included one location at a time. Explicit becomes a keystroke instead of a transcribed path; it does not become a default or a bulk toggle.
  • Permanent removal keeps its friction. The interface reuses the same confirmation the CLI uses, including typing the word for irreversible removal. A highlighted button is exactly what muscle memory triggers, which is the reason that friction exists.
  • Preview matches execution, as clean already promises. The preview is the same admission assessment execution re-verifies, and an explicit selection stays atomic: if one selected item fails preflight the whole batch is refused before anything is written.

A confirmed clean also permanently removes staging entries at least seven days old — docs/safety.md notes this happens even with an empty plan, because there is no background timer. The interface must show that alongside, and apart from, what the reader chose, so the two are never confused.

Example workflow or CLI

# today: read, transcribe, then discover that nothing was freed
degu scan
degu clean --include-review --path ~/.cache/huggingface/hub/models--a --path ~/.cache/torch/inductor
degu trash list
degu trash purge          # all of it, or nothing

# proposed
degu tui

Selective permanent removal should exist on the command line first, so the interface has something to wrap:

degu trash purge --path ~/.local/state/degu/trash/...

Affected area or ecosystem

Cleanup and trash workflow, plus presentation; no adapter or ecosystem-specific behavior.

Current workaround or alternatives

Read the scan, copy the paths you decided to clean, assemble --include-review --path ... --path ..., run it, then run degu trash purge and accept that it takes everything. For decisions a rule can express, --include-review --min-size ... --older-than ... already works well and is the right answer for scheduled cleanup; this request is about the decisions a rule cannot express.

Safety and filesystem semantics

The interface must not carry deletion capability. It produces the arguments; admission, staging, purge and the mutation lock stay where they are, and the plan is re-verified at execution rather than trusted from when it was drawn.

Eligibility does not change. Not managed cannot be selected from any surface. Needs review is included per location by an explicit act. Ready to clean is unaffected.

Selective permanent removal is a new selector, not a new mechanism: plan_expired_trash already builds a purge plan from a subset chosen by a predicate, and captures and executes those entries through the same batch path as a full purge. Adding a path predicate reuses that; it does not introduce a second way to destroy data.

Irreversible operations keep the confirmation they have today, and the interface must refuse in the same places the CLI refuses — a non-terminal, a held mutation lock, an incomplete scan that makes the plan untrustworthy.

The read-only browser from #98 is a different thing and stays useful for a different case: a report exported from a cluster and read elsewhere, where the reader cannot act because they are not on that machine. Read-only is correct there. This is about the case where the reader is on the machine and the decision is the point.

Before submitting

  • I searched the existing open and closed issues.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions