Skip to content

feat(cleanup): make idle-destroy disk-pressure-aware, remove inert runtime-gc - #48

Merged
V3RON merged 2 commits into
mainfrom
claude/issue-22-inert-features
Aug 21, 2026
Merged

feat(cleanup): make idle-destroy disk-pressure-aware, remove inert runtime-gc#48
V3RON merged 2 commits into
mainfrom
claude/issue-22-inert-features

Conversation

@V3RON

@V3RON V3RON commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Closes #22. The issue said either resolution was acceptable per feature, so: disk pressure is implemented, runtime GC is removed. Reasoning for each choice below, since they went opposite ways.

Disk pressure — implemented

Removing it would have meant dropping diskPressure.freeBytesThreshold, a config key that is already validated and documented, so the honest cheap direction was to make it do what the docs imply.

idle-destroy now reads diskFreeBytes off the view — which the reaper was already computing and no rule was reading — and shortens its own threshold from T2 to T1 when free space is under the configured threshold. No new config keys. The reason string names pressure as the cause, per safety rule 6: disk pressure (free 2GiB < 10GiB): idle 12m > T1=10m.

The behaviour deliberately does not flow through the event bus. The reaper emits disk.pressure-detected as a post-commit observer fact, edge-triggered so a sustained condition emits once per crossing rather than once per tick, but the rule stays a pure function of the view and never depends on an event having fired (safety rule 3). The existing subscription is kept so an external emitter can still wake the reaper.

One defect found in review and fixed here: the crossing check initially sat in #view(), which every run shares — so pitlane cleanup --dry-run under pressure would emit the fact, wake this reaper through its own subscription, and turn a preview into a real cleanup run. A dry run must stay a preview (safety rule 5). The fact is now noted only on runs that execute, and the test pins it by counting rule evaluations: without the guard, the preview evaluates twice — once for itself, once for the run it woke.

Runtime GC — removed

Implementing it needs an Android system-image inventory the driver doesn't expose, so it would be a feature, not a fix. runtime-gc.ts, its registration, the gc-runtime CleanupAction, and the runtime.deleted event declaration are gone, along with the docs/CLI.md and docs/ARCHITECTURE.md claims that it works. iOS runtimes stay Xcode-managed regardless.

Consequence that had to be handled: runtimeGcRule was the only entry in manualCleanupRules, and #rulesFor(name) filtered --rule against manual rules only — so removing it would have left cleanup --rule matching nothing at all. In fact --rule idle-destroy already matched nothing today, which is a live bug this surfaces. --rule <name> now selects across the rules that actually exist, so both idle-shutdown and idle-destroy work, manualCleanupRules is gone rather than left as an empty exported list, and list --rules reports the real registry.

Tests

  • idle-destroy: destroys at T1 under pressure with pressure named in the reason; still waits for T2 when not under pressure; never proposes a leased device under pressure (safety rule 2).
  • reaper: emits once per crossing and not per sustained tick, and again after recovering and re-crossing; --rule selects by name across the registered rules; the dry-run test above.

Verification

pnpm run check green (505 unit, 28 e2e) and pnpm fallow --ci clean — re-run independently after the review fix, not only as reported.


Generated by Claude Code

claude added 2 commits August 20, 2026 19:41
…ntime-gc

Resolves #22. Two documented features did nothing: disk.pressure-detected
was declared and subscribed to but never emitted, and runtime-gc always
returned no proposals. A documented no-op is worse than an absent feature
because it reads as working, so disk pressure would never get investigated.

Disk pressure: implemented. idle-destroy now reads view.diskFreeBytes
directly and, once free space drops under diskPressure.freeBytesThreshold,
destroys shutdown devices past T1 (idle.shutdownAfterMs) instead of waiting
for T2 (idle.deleteAfterMs) -- the rule stays a pure function of the view,
never depending on the event having fired. The reaper now emits
disk.pressure-detected itself, edge-triggered on the not-under-pressure ->
under-pressure crossing, so a sustained low-disk condition emits once
instead of once per tick; the reaper keeps its existing subscription to the
event for any future external emitter.

Runtime GC: removed. Deleted runtime-gc.ts and its registration, the
gc-runtime action, and the runtime.deleted event declaration -- nothing
implemented or emitted either. This left manualCleanupRules with a single,
now-removed member and CleanupReaper#rulesFor filtering --rule against it,
so `pitlane cleanup --rule <name>` matched nothing for any rule name
(including today's already-nonfunctional --rule idle-destroy). --rule now
selects by name across the automatic rules that actually exist, and the
now-pointless manualCleanupRules export is gone.

Docs updated to match: EVENTS.md flips disk.pressure-detected to
implemented (emitter CleanupReaper) and drops the runtime.deleted row;
ARCHITECTURE.md and CLI.md describe only the rules and --rule behavior that
exist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The crossing check sat in #view(), which every run shares -- so `pitlane
cleanup --dry-run` under pressure would emit disk.pressure-detected, wake
this reaper through its own subscription, and turn a preview into a real
cleanup run. A dry run must stay a preview (safety rule 5).

The fact is now noted only on runs that actually execute. The test pins it
by counting rule evaluations: without the guard the preview evaluates twice,
once for itself and once for the run it woke.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GbpHvzYe8vEs71QHbpAhyT
@V3RON
V3RON merged commit 2d9688c into main Aug 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resolve two documented-but-inert features: disk pressure and runtime GC

2 participants