Skip to content

feat: reclaim database space after session cleanup and add a stop button - #14540

Merged
marius-kilocode merged 6 commits into
Kilo-Org:mainfrom
vkeerthivikram:feature/session-cleanup-reclaim-stop
Sep 25, 2026
Merged

marius-kilocode merged 6 commits into
Kilo-Org:mainfrom
vkeerthivikram:feature/session-cleanup-reclaim-stop

Conversation

@vkeerthivikram

@vkeerthivikram vkeerthivikram commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Issue

Fixes #14538
Fixes #14539

Context

cleanup never gave disk space back. My kilo.db stayed at 367MB after a pass that emptied 90% of it. And once a pass started there was no way to stop it.

Implementation

After the deleting phase the pass reads freelist_count vs page_count and vacuums when free space clears both floors, 16MB and 20% of the file, then truncates the wal. Skipped when cancelled or when the numbers don't justify a rebuild. A busy database logs and moves on, the pass can't fail because of the vacuum.

New POST /kilocode/retention/cancel. The pass checks a flag between removals, keeps what it already deleted, skips the rest, and records a partial result with cancelled: true. The spacing window still counts, so the daily trigger doesn't restart the whole job later. On cancel, failed counts only sessions that were actually attempted, not the ones never reached.

Extension side is a Stop button next to Run while a pass is live, a stopping phase in the progress text, and the last run line marking interrupted runs. All 21 locales plus the checkpoints docs page.

Left out on purpose: the event table (269MB of my 367MB) is untouched. Capping per-session event growth is a separate discussion.

Screenshots / Video

Screenshot_2026-09-24_17-34-24

How to Test

Manual/local verification

Everything below was run by the coding agent on my machine, I haven't repeated the commands by hand yet.

  • bun test ./test/kilocode/session/retention.test.ts ./test/kilocode/session/retention-reclaim.test.ts from packages/opencode, 32 passing. Covers cancel mid-deleting, cancel during scanning, cancel with no pass, vacuum thresholds, real file shrink on a disk-backed db.
  • bun test tests/unit/cleanup-poll.test.ts from packages/kilo-vscode, 10 passing.
  • typecheck on both packages, knip, check-kilocode-change, source-links, all clean.
  • bun run test:httpapi from packages/opencode, all three modes, 333 scenarios each, 0 missing. (CI caught that the new route needed an exerciser scenario, this is the run after adding it.)
  • for the docs edit, bun run --filter @kilocode/kilo-docs test, 22 passing, and check-md-table-padding reports nothing.
  • live run against bun dev serve with a temp KILO_DB and 4000 seeded expired sessions. Caught the pass in deleting, cancel returned requested: true, it ended with deleted: 6, cancelled: true and the rest untouched. A second full pass shrank the file. The same reclaim path on a copy of my real db took it from 367MB to 36MB.

Reviewer test steps

  1. KILO_DB=/tmp/t.db KILO_CONFIG_CONTENT='{"retention":{"enabled":true,"maxAgeDays":1}}' bun dev serve --port 0
  2. Create a session, then age it with UPDATE session SET time_created = time_created - 172800000, time_updated = time_updated - 172800000
  3. POST /kilocode/retention/run with {"force":true}, poll GET /kilocode/retention until phase is deleting, then POST /kilocode/retention/cancel
  4. Status shows a partial result with cancelled: true. Run again without cancelling and the file shrinks.
  5. In the extension: Settings, Checkpoints, Run Cleanup Now, Stop while it runs.

Blocked checks and substitute verification

Didn't run the full extension suite. The targeted unit tests, typecheck and the live backend run cover the changed paths. Haven't verified the UI by hand yet, screenshot still pending.

Checklist

  • Issue linked above, or exception explained
  • Tests/verification described
  • Screenshots/video included for visual changes, or marked N/A
  • Changeset considered for user-facing changes
  • I personally reviewed the diff and can explain the changes, including any AI-assisted work.

Session cleanup deleted rows but never shrank kilo.db, and a pass could
not be stopped once started. A pass now vacuums the database when freed
pages clear absolute and relative floors, and a new retention cancel
endpoint lets clients stop the active pass; already-deleted sessions
stay deleted and the partial result is recorded. The VS Code settings
screen gains a Stop button plus cancelling progress and interrupted
last-run states.

docs-tmp

regenerated visual-regression baselines (not part of the cleanup branch)
@vkeerthivikram
vkeerthivikram force-pushed the feature/session-cleanup-reclaim-stop branch from 2291955 to 3b0f9b0 Compare September 24, 2026 12:14
@vkeerthivikram
vkeerthivikram marked this pull request as ready for review September 24, 2026 12:24
Comment thread packages/opencode/src/kilocode/session/retention.ts
Comment thread packages/opencode/src/kilocode/session/retention.ts
Comment thread packages/opencode/src/kilocode/session/retention.ts
Comment thread packages/opencode/src/kilocode/session/retention.ts
Comment thread packages/kilo-vscode/src/KiloProvider.ts Outdated
Comment thread packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts Outdated
Comment thread packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts

Provide exactly one of `--prompt` or `--prompt-stdin`. For example, read a multiline prompt from a file with `kilo cloud start --repo owner/repo --prompt-stdin < prompt.txt`.

### kilo cloud send

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.

WARNING: Unrelated removal of accurate --prompt/--prompt-stdin documentation.

This PR deletes two sentences documenting --prompt/--prompt-stdin for kilo cloud start and kilo cloud send, which has nothing to do with session cleanup. The flag still exists (packages/opencode/src/kilocode/cli/cmd/cloud-stdin.ts) and is still documented on the cloud-agent page, so the note remains correct. This looks accidental (the commit message even carries a docs-tmp line); please restore it or move it to a separate docs change.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@vkeerthivikram vkeerthivikram Sep 24, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

To be clear on where this came from: the deletion rode along with the SDK regeneration, which the contributing guide requires after adding an endpoint. Those two sentences were hand-added on main after the file was last generated, so the generator does not know them. I reran ./script/generate.ts after today's upstream sync and it produced no changes at all, the prose never comes back from generation. Leaving the file exactly as the generator emits it.

@kilo-code-bot

kilo-code-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The previous findings are resolved at 3401413069: KiloProvider now preserves the real cancel() boolean (service?.cancel().catch(() => false)), and the cancel/vacuum accounting and Stop-button findings were fixed in 9f58f3a7. New test coverage (cleanup-stop.test.ts, the 90-day retention case) exercises the real handler and selection logic correctly.

Files Reviewed (3 files)
  • packages/kilo-vscode/src/KiloProvider.ts
  • packages/kilo-vscode/tests/unit/cleanup-stop.test.ts
  • packages/opencode/test/kilocode/session/retention.test.ts
Previous Review Summaries (2 snapshots, latest commit 9f58f3a)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 9f58f3a)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/src/KiloProvider.ts 3558 cancel() boolean is discarded: the new sealed guard makes the endpoint return requested: false during VACUUM, but .then(() => true, ...) reports success anyway, so a Stop clicked then is a silent no-op

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts 34 stop() now covers the manual-run path via this.run, but a backend-triggered pass reporting pending: true without progress (and no this.run) still early-returns while the Stop button is visible/enabled

Resolved in 9f58f3a7: cancelled-pass deleted/failed accounting (cascade children, attempted-but-failed roots), scanning-phase cancel no longer reverts to "deleting", reclaim() re-interrupts instead of swallowing interrupts, and the stuck halt is reset once progress disappears. The --prompt-stdin note in cli-reference.md was re-checked: that file is fully regenerated by script/generate-cli-docs.ts and marked "do not edit manually", so the author's explanation holds.

Files Reviewed (5 files)
  • packages/opencode/src/kilocode/session/retention.ts
  • packages/opencode/test/kilocode/session/retention.test.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts
  • packages/kilo-vscode/tests/unit/cleanup-poll.test.ts
  • packages/kilo-vscode/src/KiloProvider.ts (carried-forward finding)

Fix these issues in Kilo Cloud

Previous review (commit f010300)

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 5
SUGGESTION 3
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/kilocode/session/retention.ts 91 Cancelled pass under-reports deleted for cascaded children; scanning-phase cancel reverts to "deleting"
packages/opencode/src/kilocode/session/retention.ts 436 Cancelled pass omits attempted-but-failed root removals from failed
packages/kilo-vscode/src/KiloProvider.ts 3558 Boolean returned by cancel() is discarded
packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts 34 Stop silently no-ops until the first progress response
packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md 1044 Unrelated removal of accurate --prompt-stdin docs

SUGGESTION

File Line Issue
packages/opencode/src/kilocode/session/retention.ts 418 Stop during reclaim reports requested but records a non-cancelled result
packages/opencode/src/kilocode/session/retention.ts 422 reclaim() swallows interrupts
packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts 54 halt can stay set forever if the stop response never arrives
Files Reviewed (41 files)
  • packages/opencode/src/kilocode/session/retention.ts
  • packages/opencode/src/kilocode/server/httpapi/groups/kilocode.ts
  • packages/opencode/src/kilocode/server/httpapi/handlers/kilocode.ts
  • packages/opencode/test/kilocode/session/retention.test.ts
  • packages/opencode/test/kilocode/session/retention-reclaim.test.ts
  • packages/opencode/test/kilocode/server/httpapi-exercise-scenarios.ts
  • packages/kilo-vscode/src/KiloProvider.ts
  • packages/kilo-vscode/src/services/task-cleanup/retention.ts
  • packages/kilo-vscode/tests/unit/cleanup-poll.test.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/CheckpointsTab.tsx
  • packages/kilo-vscode/webview-ui/src/components/settings/cleanup.ts
  • packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts
  • packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts
  • packages/kilo-vscode/webview-ui/src/i18n/*.ts (21 locales)
  • packages/kilo-docs/pages/code-with-ai/features/checkpoints.md
  • packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md
  • .changeset/session-cleanup-stop.md
  • .changeset/session-cleanup-vacuum.md
  • packages/sdk/js/src/v2/gen/sdk.gen.ts (generated)
  • packages/sdk/js/src/v2/gen/types.gen.ts (generated)
  • packages/sdk/openapi.json (generated)

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

vkeerthivikram and others added 4 commits September 24, 2026 18:54
A cancelled pass now counts children removed by earlier root cascades
(progress sampling also runs while cancelling), counts root removals
that failed before the cancel, and keeps its cancelling phase instead of
flipping back to deleting. Cancel is sealed once the deletion sweep
finishes so it can not report success during the vacuum, and the vacuum
no longer swallows interrupts. The settings poll can stop a pass while
its run reply is still outstanding and forgets a stop once no progress
remains.
@marius-kilocode

Copy link
Copy Markdown
Collaborator

The distinction is between using requested and preserving the value returned by cancel(). .then(() => true, () => false) converts every resolved response, including false, into true. If cancellation returns false and the status request then fails, the error flag is incorrectly omitted.

I changed this locally to const requested = await service?.cancel().catch(() => false) and added a regression test covering both boolean results with status available/unavailable. The fix is committed as 3401413069, but HTTPS and SSH pushes to this fork both fail in Git LFS lock verification with an authentication/push-access error, so the PR branch is not updated yet. I have not bypassed the hook or merged the PR.

Validation passed: 15 focused extension tests, 35 backend retention/reclaim tests including a new 90-day preservation test, extension compile/lint/typechecks, CLI typecheck, knip, and annotation guards. In isolated VS Code with 90-day retention and synthetic sessions, Stop recorded a partial result; rerunning removed only the remaining expired fixtures. Both 60-day and 89-day sessions survived. No real user database or settings were accessed.

The generated-docs explanation checks out; restoring prose directly in generated output is not needed here.

@marius-kilocode

Copy link
Copy Markdown
Collaborator

The fix and regression tests are now pushed in 3401413. The earlier push failure was specific to the SSH identity/transport used for Git LFS. Using the repository maintainer SSH alias succeeded without disabling hooks or checks. The local verification results above apply to this commit; waiting for its CI before merging.

@marius-kilocode marius-kilocode left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed the cleanup and cancellation changes, including the cancellation-result correction in 3401413. Focused regression tests and isolated VS Code Stop/rerun verification passed. The 90-day tests preserve younger sessions and parents with fresh or busy descendants. Approval is subject to required CI checks passing.

@marius-kilocode
marius-kilocode enabled auto-merge (squash) September 25, 2026 07:49
@marius-kilocode
marius-kilocode merged commit 277103f into Kilo-Org:main Sep 25, 2026
35 checks passed
@marius-kilocode

Copy link
Copy Markdown
Collaborator

Thanks!

@vkeerthivikram

Copy link
Copy Markdown
Contributor Author

you're right. i checked that requested was used and stopped there, didn't notice .then(() => true) makes it always true no matter what cancel returned. catch(() => false) it is.

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.

[FEATURE]: Way to stop a session cleanup pass once it is running kilo.db keeps growing and a cleanup pass never shrinks it

2 participants