Skip to content

fix(browser): guest-retention polish — LRU across kill-switch, release veto on interrupted downloads - #12232

Merged
brennanb2025 merged 1 commit into
mainfrom
brennanb2025/guest-retention-pass3-polish
Aug 4, 2026
Merged

fix(browser): guest-retention polish — LRU across kill-switch, release veto on interrupted downloads#12232
brennanb2025 merged 1 commit into
mainfrom
brennanb2025/guest-retention-pass3-polish

Conversation

@brennanb2025

Copy link
Copy Markdown
Contributor

Summary

Two robustness follow-ups to #12194's browser-guest retention budget, staged by the safety-review loop's third pass before its session ended (I committed its staged work verbatim; provenance noted in the commit body). Neither is release-gating: both edge cases fail toward retaining extra memory — the pre-#12194 status quo — never toward destroying something in use.

  1. Recency bookkeeping now runs even while the retention kill switch is off, so re-enabling the switch evicts in true least-recently-activated order instead of worktree-list order.
  2. An interrupted download now releases the eviction veto (new onDownloadProgress handling for interrupted/null states), so a stuck download entry can't pin a worktree as never-evictable forever.

Screenshots

No visual change.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions, or explained why tests were not needed

browser-page-download-activity.test.ts extended for the progress/interrupted listener lifecycle (listener add/remove accounting included). PR CI runs the full suite; the delta is 6 files / ~74 lines originally reviewed inside the #12194 until-clean loop.

AI Review Report

These changes ARE the output of the #12194 adversarial review loop (pass 3), which had already produced two merged fixes (surface-stays-mounted eviction; download veto + kill switch) in that PR. Risks checked there: eviction must never destroy an in-use guest (this PR widens the protection to interrupted downloads) and kill-switch toggling must not corrupt LRU order. Cross-platform: renderer-only logic, no paths/shortcuts/shell/Electron-main surface.

Security Audit

No new inputs, IPC, command execution, or secrets. The new listener consumes the existing preload onDownloadProgress bridge events only.

Notes

Not needed for the v1.4.165 cherry-picks; rides the next release train. If the rc.1 bake shows any retention oddity, this PR plus the in-code kill switch are the levers.

…nload veto on interrupt

Two robustness follow-ups from the #12194 safety-review loop (pass 3),
staged by the reviewer before its session ended; both fail toward extra
retention only:
- recency bookkeeping now runs while the retention kill switch is off, so
  re-enabling evicts in true LRU order instead of worktree-list order
- interrupted downloads release the eviction veto instead of pinning the
  worktree as downloading forever
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Browser guest recency is updated for active worktrees before retention-budget eviction checks. Download tracking now records per-download active state, handles interruption and resumption events, ignores invalid progress events, and removes progress listeners during cleanup. Tests cover these state transitions, duplicate and unknown events, balanced activity counts, and listener removal.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies both primary fixes: LRU tracking across the kill switch and eviction-veto release for interrupted downloads.
Description check ✅ Passed The description covers all required sections and accurately explains the changes, tests, review risks, security audit, and lack of visual changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 422022dc-e39b-4eac-9e51-694e7541da06

📥 Commits

Reviewing files that changed from the base of the PR and between 93a2ad8 and 5ff64da.

📒 Files selected for processing (3)
  • src/renderer/src/components/Terminal.tsx
  • src/renderer/src/components/browser-pane/browser-page-download-activity.test.ts
  • src/renderer/src/components/browser-pane/browser-page-download-activity.ts

Comment on lines +22 to +38
const removeListener = (): void => {
removedListenerCount += 1
}
vi.stubGlobal('window', {
api: {
browser: {
onDownloadRequested: (callback: DownloadRequestedCallback) => {
requestedCallbacks.push(callback)
return () => {
removedRequested = true
}
return removeListener
},
onDownloadProgress: (callback: DownloadProgressCallback) => {
progressCallbacks.push(callback)
return removeListener
},
onDownloadFinished: (callback: DownloadFinishedCallback) => {
finishedCallbacks.push(callback)
return () => {
removedFinished = true
}
return removeListener

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Track each listener removal separately.

The shared removeListener makes removedListenerCount === 3 pass if cleanup invokes one unsubscribe callback three times. Return distinct removal spies for onDownloadRequested, onDownloadProgress, and onDownloadFinished. Assert that each spy is called once.

Also applies to: 130-130

@brennanb2025
brennanb2025 merged commit 73e7df7 into main Aug 4, 2026
43 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.

1 participant