Repository navigation
fix(opencode): keep overlay manifest cleanup inside owned directories - #24763
Conversation
Reuse captured composer readiness on local and paired execution hosts and revoke launching-shell paste anchors. Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
Co-authored-by: Adnan Khan <adnank11427@gmail.com>
Reuse captured composer readiness on local and paired execution hosts and revoke launching-shell paste anchors. Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This run is scoped to what changed since the prior pullfrog review (a6879b0): the head merged the declared base into the branch. The PR's own authored layer is unchanged.
- Base merge brings the branch current —
d12f6b5emerges the declared basenwparker/OpenCode-Native-Prompt-Intent(tip85efe85e) into the head. The merge is clean: head vs its base is still exactly the five authored overlay-cleanup files (+202/−6), byte-identical to the previously approved state, so no PR-authored content changed. - Merged-in
location.syncstartup hydration — the merge pulls the base'sopencode-startup-prompt-source.tschange into the head tree: the plugin now requiresctx.data.location.sync, calls it once at setup, and the delivery poll returns early untillocationReady. These files are identical to the base tip and do not appear in this PR's own diff; I re-read both the change and its tests against OpenCode v2.0.16 (location.syncloads location + config;listis a pure read) and found no claim-before-hydration race and no fail-open path.
The confinement logic itself is untouched by this merge and remains as previously verified against adversarial manifest inputs.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Scoped to what changed since the prior pullfrog review (d12f6b5e): the head merged the declared base's new tip 1dc953cf8c into the branch, which advances the base-owned startup-hydration gating. The PR's authored overlay-cleanup layer is unchanged.
- Base merge keeps the layer current —
0dd7371fmergesnwparker/OpenCode-Native-Prompt-Intent(1dc953cf8c) into the head. Head vs base is still exactly the five authored overlay files (+202/−6), byte-identical to the previously approved state. - Startup readiness is now location-bound — the merged-in plugin no longer latches a single
locationReadyboolean at setup. The poll deriveslocationKey(location)fromctx.locationand only proceeds when it matchesreadyLocation; on any change it re-invokesctx.data.location.sync, clears readiness, and re-checks the key after the claim await and again immediately beforekeymap.dispatch. These two files are identical to base tip, so they are base-owned and outside this PR's own diff. - New regression tests — four cases pin the behavior: a directory change mid-sync triggers a second sync to the new location and delays the claim until it resolves; no sync before a concrete location exists; a workspace-only change re-syncs; and a claim granted after the composer location changes never inserts or dispatches.
I verified the new ref shape against OpenCode v2.0.16: LocationRef is { directory: AbsolutePath, workspaceID?: WorkspaceID } (packages/schema/src/location.ts) and the location query keys on directory (packages/protocol/src/groups/location.ts), so { directory, workspaceID } is exactly valid. The gating is fail-closed: an unresolved or rejected sync drops the intent, and every asynchronous boundary before dispatch re-checks the location key.
The confinement logic itself is untouched by this merge and remains as previously verified against adversarial manifest inputs.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
Preserve OpenCode launch ownership and location-bound startup claims while inheriting current terminal observations and installer corrections.
Preserve OpenCode launch ownership and location-bound startup claims while inheriting current terminal observations and installer corrections.
Preserve OpenCode launch ownership and location-bound startup claims while inheriting current terminal observations and installer corrections.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This run is scoped to what changed since the prior pullfrog review (0dd7371f): the head merged the declared base's new tip, which is itself a merge of current main. The PR's authored overlay-cleanup layer is unchanged.
- Clean base merge keeps the layer current —
15f3e7abmergesnwparker/OpenCode-Native-Prompt-Intent(89aa00a9) into the head.git show --cc --name-onlyfinds no conflict or evil-merge hunks, so it is a clean auto-merge; head vs the declared base is still exactly the five authored overlay files (+202/−6), andgit diff 0dd7371f HEADfor those five files is empty. - Merged-in main delta stays outside this layer — the ~150-file net delta between the two heads is main's content (browser, claude, ipc, runtime, renderer, shared agent-title). None touch
src/main/opencode/orsrc/main/pty/, so no module the authored files import changed with the merge.
The confinement logic itself is untouched by this merge and remains as previously verified against adversarial manifest inputs (absolute paths, .. traversal, dangling/intermediate symlinks, Windows junctions).
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
Preserve safe overlay cleanup while inheriting the retryable startup-claim transport response.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (5)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughOverlay cleanup now checks ancestor paths and refuses removal when an ancestor is a symlink or has an unexpected lookup error. OpenCode overlay setup validates the overlay root, overlay directory, and plugins directory. If validation fails, it returns the source configuration directory. Manifest cleanup uses scoped removal. Tests cover symlinked paths, missing paths, stale plugin entries, and invalid manifest data. Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The overlay confinement changes are mergeable after normal checks. A pre-existing replacement race remains a separate hardening concern, but this change does not worsen it. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change strengthens cleanup boundaries without expanding filesystem authority. A pre-existing directory-replacement race remains, but the reviewed changes reduce exposure to already-replaced directories rather than introduce or worsen that race. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
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. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This run is scoped to what changed since the prior pullfrog review (15f3e7ab): the head merged the current main tip into the branch. The PR's authored overlay-cleanup layer is unchanged.
- Clean main merge keeps the layer current —
a7540059mergesmain(e8310d5a4f, the #24762 startup-brief fix) into the head.git show --cc --name-onlyreports no conflict or evil-merge hunks, so it is a clean auto-merge. - Authored overlay layer is byte-identical —
git diff 15f3e7ab a7540059 -- src/main/opencode src/main/ptyis empty. All five authored files, the inherited manifest reader, and every sibling module in those two directories are unchanged from the previously approved state. - Merged main delta stays outside this layer — the ~219-file net delta between the heads is main's content. None of it touches
src/main/opencode/orsrc/main/pty/, and the shared modules the authored files import (app-environment,opencode-config-directory,opencode-tui-plugin-install,opencode-plugin-atomic-write) are not in it, so no module this layer depends on changed with the merge.
The confinement logic itself is untouched by this merge and remains as previously verified against adversarial manifest inputs (absolute paths, .. traversal, dangling/intermediate symlinks, Windows junctions).
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

ELI5
Stale overlay entries could direct cleanup outside the owned directory or through a replaced parent. Cleanup now checks the owned boundary and rejects redirected parents.
What Changed
Remove only entries recorded in the overlay manifest, after checking that their parent directories still belong to Orca and are not symbolic links. Retain the complete original cleanup contribution on main; the startup and manifest prerequisite from #24762 has merged.
Why
Checking each recorded entry preserves runtime-created directories and the user's source configuration. Replacing the entire overlay would lose those distinctions.
Linked Issue
Focused contribution from #13287, following merged #24762. #13287 remains open for its other work.
Visual Proof
N/A — background filesystem cleanup adds no rendered controls. The retained combined OpenCode startup evidence is linked below.
Testing
On exact source
a7540059, 169 tests across 14 files, all three desktop typechecks, full owned TypeScript lint, the configured repository quality scan and formatting pass. Formatting checked 116 eligible files; four timing records are excluded by the existing formatter configuration. Recorded test processes closed. Tests use private ephemeral loopback ports; the process receipt is not an exhaustive endpoint inventory.Installed OpenCode 2.0.16 reproduced lost startup authorization and incorrect inherited configuration in the retained earlier runs. The repaired combined
c8fdfdbeapp completed fresh and nested Unicode startup turns, used one combined status/prompt overlay, claimed each brief once, preserved the original user configuration and reported canonical working → done. Its genuine worker selected the app's private CLI and completedworker_doneexactly once. All 319 recorded process incarnations and four private ports closed. Screenshots and actual evidence remain pinned to that source on main2b1acd0d. This publication has its own static checks and does not claim an app run on the current commit. Fresh public CI is pending.Review
Two independent reviews checked all 124 retained files and every other main file. The normal merge retains predecessor and contributor ancestry; its resulting tree is main
e8310d5aplus the five cleanup files. The two owned conflicts select the merged startup lifecycle and the reviewed cleanup service. Mainc4e8735fadds 21 files with no overlap in this scope, so CI will test the combined merge.Agent skill upstream boundary
Notes
Credit Adnan Khan (@akhan157). Retain the complete original cleanup scope and author ancestry, including its earlier reader prerequisite. Local, SSH and folder workspaces continue to use the existing execution-host cleanup boundary; no remote protocol changes are introduced.
Checklist