Skip to content

fix(core): preserve approvals across location cleanup - #46509

Closed
kitlangton wants to merge 1 commit into
v2from
hidden-approval
Closed

kitlangton wants to merge 1 commit into
v2from
hidden-approval

Conversation

@kitlangton

Copy link
Copy Markdown
Contributor

Why

Returning to a session that has waited for permission for over an hour can show an active spinner with no approval to answer. The automatic location sweep invalidates its cache entry despite the running session still borrowing it. The old permission service remains alive with the waiting tool, while subsequent API reads see a different instance with no pending requests.

What Changes

Automatic cleanup now skips locations with outstanding references. The expired entry remains eligible for cleanup on the next sweep after its final borrower releases it. The reference check and cache removal run without an automatic scheduler yield between them.

Scenario Before After
Permission wait exceeds the activity timeout Live location detached from the cache Same location remains discoverable
Reopen the session Spinner, no approval Original approval can be answered
Approve the search No reachable request Tool completes and session becomes idle
Expired location has no borrowers Evicted Still evicted

Demo

comparison.mp4

Matched OpenCode Drive runs: left is base b0402f5a34, right is fix 7b73f20fcc. Both use the same isolated project, simulated model, real glob tool, permission service, production TUI, and Enter interaction. A timing-only Bun preload shortens the real automatic cleanup timeout from one hour to eight seconds, swept every second. No manual invalidation or staged UI is used. The shorter clip holds its final frame briefly to align the comparison.

The runnable fixture and instructions are in script/repro/hidden-approval.md.

Scope

This fixes automatic location eviction while resources are borrowed. It does not change permission policy, restart recovery, or explicit debug invalidation. Existing stranded executions in an already-running server are not retroactively reattached.

Verification

cd packages/core
bun run test test/location-layer.test.ts test/permission.test.ts
bun typecheck

# From the fix checkout root; both checkouts have dependencies installed.
cd ../..
export OPENCODE_DRIVE_MEDIA_DIR="$PWD/.cache/hidden-approval"
OPENCODE_REPRO_BEFORE=1 OPENCODE_DEV=/path/to/base \
  opencode-drive run script/repro/hidden-approval.ts
OPENCODE_DEV="$PWD" opencode-drive run script/repro/hidden-approval.ts
  • 133 tests pass; core typecheck and formatting checks pass. The pre-push typecheck hook also passed all 33 tasks.
  • The new regression fails before the fix at 61 virtual minutes, then passes with the fix and confirms eviction after release.
  • Drive asserts the baseline has zero pending approvals and remains active. The fixed run retains the same request ID, accepts approval, completes the real search, and becomes idle.

@kvnloo

kvnloo commented Sep 1, 2026

Copy link
Copy Markdown

Live check on packages/core/src/location-activity.ts (PR head 7b73f20): the sweep used to invalidate every expired location. A permission wait owns the Location without Session activity, so after the TTL the cache detaches while the borrower is still alive. Reopen shows a spinner and zero pending approvals.

Fix: skip eviction when rcMap refCount > 0, and run the check + delete under References.PreventSchedulerYield so a new borrower cannot sneak in between. Regression advances 61 virtual minutes and asserts the same Location.Service stays discoverable, then evicts after Scope.close. Drive repro + preload in script/repro/hidden-approval*. MERGEABLE/CLEAN. 0 comments.

I would merge. Scope note from the PR body is right: stranded executions on an already-running server are not retroactively reattached. No ask to widen that here.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants