Skip to content

feat(server): add safe service runtime pruning - #7811

Open
paulcatamio wants to merge 2 commits into
pingdotgg:mainfrom
paulcatamio:fix/service-runtime-prune
Open

feat(server): add safe service runtime pruning#7811
paulcatamio wants to merge 2 commits into
pingdotgg:mainfrom
paulcatamio:fix/service-runtime-prune

Conversation

@paulcatamio

@paulcatamio paulcatamio commented Aug 21, 2026

Copy link
Copy Markdown

What Changed

  • Add t3 service prune with a --dry-run preview.
  • Remove only completed exact-version installs older than the active runtime.
  • Keep the active version and both versions referenced by the latest update record, and refuse to prune while an update is pending.
  • Ignore staging directories, incomplete installs, symlinks, unexpected directory names, and newer versions.
  • Document the command and its update-safety boundary.

Why

Service updates install immutable runtimes so the launcher can roll back, but old installs currently accumulate without a supported cleanup path. This adds an explicit maintenance command that uses launcher-owned state and does not stop or restart the service.

Testing

  • pnpm exec vp test run apps/server/src/cloud/pinnedRuntime.test.ts apps/server/src/cloud/bootService.test.ts apps/server/src/cli/service.test.ts (30 tests)
  • pnpm --filter t3 typecheck
  • Targeted vp lint and vp fmt --check on the changed files
  • pnpm --filter t3 build:bundle
  • node apps/server/src/bin.ts service prune --help
  • Manual WSL prototype validation: pruned 11 old nightly runtimes and recovered 6.73 GiB while the service PID, restart count, and HTTP health stayed unchanged

Model and harness: OpenAI Codex; repository toolchain plus manual WSL service validation.


Note

Medium Risk
Deletes versioned runtime directories on disk, so incorrect candidate selection could remove a needed rollback install. Guards (pending-update refusal, sentinel/realpath checks, protected versions) keep the blast radius limited.

Overview
Adds t3 service prune so old pinned service runtimes can be cleaned up without stopping or restarting the background service. --dry-run lists the same candidates without deleting them.

Only completed exact-version installs older than the active runtime are removed. The active version and both versions named by the latest update record are kept. Incomplete installs, staging dirs, symlinks, unexpected names, and newer versions are ignored. Prune refuses to run if launcher state is missing/invalid or a remote update is still pending.

Reviewed by Cursor Bugbot for commit 2a2ac12. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add t3 service prune command for safe runtime pruning

  • Adds a prune subcommand to the service CLI with a --dry-run flag for previewing removals without touching the filesystem.
  • Implements prunePinnedRuntimes in pinnedRuntime.ts, which selects only completed, unreferenced runtime versions strictly older than the active version and not named in a pending update. Symlinks, staging dirs, incomplete runtimes, and protected versions are preserved.
  • Extends BootService in bootService.ts with a prune method that refuses when service state is missing/invalid or an update is pending, and deletes without restarting the service.
  • Adds formatting in service.ts and user docs in background-service.md.
  • Behavioral Change: prune deletes runtime version directories recursively with force; it fails closed on missing state and refuses during pending updates. Reviewers should verify candidate filtering in prunePinnedRuntimes and the protected-set logic around activeVersion/update.fromVersion/update.targetVersion.

Macroscope summarized 2a2ac12.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 61ef50f7-6295-44a2-84b8-717b47b1de7b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 21, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new prune error modeling in apps/server/src/cloud/bootService.ts. Everything else (inline prune on the Context.Service interface, BootService["Service"]["prune"] typing, namespace imports, make/layer placement, focused tests for the new behavior) follows the conventions.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/cloud/bootService.ts
@macroscopeapp

macroscopeapp Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a new service prune CLI command that performs filesystem deletions. New features involving destructive operations warrant human review, even with the safety checks and dry-run support included.

You can add or adjust custom eligibility rules. Learn more.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant