Skip to content

fix(core): folder approvals use the project's own files, not this machine's disk - #59089

Merged
kitlangton merged 2 commits into
devfrom
refactor/fileaccess-environment
Oct 26, 2026
Merged

kitlangton merged 2 commits into
devfrom
refactor/fileaccess-environment

Conversation

@kitlangton

@kitlangton kitlangton commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Folder approvals now pick the right folder and repository on projects that don't live on this machine's disk.
When a tool touches a path outside the project, OpenCode asks to approve that folder and offers to "always allow" the repository it's in; for in-memory or remote projects it checked this machine's disk instead of the project's. Normal local projects are not affected.

❌ Before

  1. A tool on a remote project touches /remote/repo/src.
  2. OpenCode checks this machine's disk, where that path doesn't exist. ❌
  3. It asks to approve the parent folder, and "always allow" can't find the repository (or picks a same-named one on this machine). ❌

✅ After

  1. A tool on a remote project touches /remote/repo/src.
  2. OpenCode checks the project's own file system, following symlinks.
  3. It asks to approve /remote/repo/src, and "always allow" saves at /remote/repo.
- is this path a folder?    -> ask this machine's disk
- where is the repository?  -> walk up this machine's disk looking for .git / .hg
+ is this path a folder?    -> ask the project's file system (follows symlinks)
+ where is the repository?  -> walk up the project's file system looking for .git / .hg

📊 Proof

On a non-local project, approving… Before After
an outside folder that exists ❌ asks for its parent ✅ asks for that folder
a symlink to an outside folder ❌ asks for its parent ✅ asks for the linked folder
a new file inside an outside repository ❌ "always allow" misses the repository ✅ saved at the repository root
the same on a local project ✅ ✅ unchanged (new test pins it)

The new in-memory test fails on dev and passes here; the targeted core and server tests and the core typecheck pass.

👀 Read: file-access.ts (resolve) and the new repository-finding loop in project.ts. Two small edge shifts: a symlinked outside file that exists but can't be opened now errors instead of counting as a file, and the error type is now the file layer's error instead of the old disk helper's (all callers still typecheck). The rest is routine.

🔍 First step of a plan to route every file and process call through one project file layer, one service per PR · no user reports · nothing removed from the worker server yet

Checks run
  • bun test test/file-access-path.test.ts test/file-access.test.ts test/file-mutation.test.ts test/environment.test.ts test/tool-read.test.ts test/tool-write.test.ts test/tool-edit.test.ts test/tool-patch.test.ts test/tool-search.test.ts test/session-instructions.test.ts test/vcs.test.ts test/plugin.test.ts: pass
  • packages/server bun test test/workerd.test.ts: pass
  • bun run typecheck in packages/core: pass

@opencode-agent opencode-agent 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.

Looks sound. On the base, the new memory-driver test fails because the host disk is consulted. With this change, the external directory, the symlinked directory and the enclosing .git root are all resolved through the Location's driver. The related core tests and packages/server workerd.test.ts pass, and tsc -b type-checks cleanly.

Public API is unchanged. Environment.exists is a new internal helper, and Project.root now takes any { exists } object, which FSUtil still satisfies.

One non-blocking note: on workspace-adaptor Locations, Files is backed by execDefaults, which spawns one process per stat. For an external path outside any repository, Project.root makes up to two exists calls (.git, .hg) for every directory up to /. That means roughly 2×depth process spawns each time an external path is resolved. This may be worth a follow-up if adaptor round trips are slow, for example with a single driver-side walk-up.

@opencode-agent opencode-agent 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.

The new commit looks fine. FileAccess.resolve and authorizeRead now fail with Environment.Failed instead of FSUtil.Error. No caller handled the old error type, and the patch tool already formats Environment.Failed. Project.root returning current gives the same result as before. On this head, tsc -b passes, and the related core tests and workerd.test.ts pass.

The public API is unchanged: the new error type only affects the internal FileAccess.Interface, which isn't exposed through the SDK or plugin packages.

@kitlangton kitlangton changed the title refactor(core): route FileAccess through Environment refactor(core): folder-permission checks use the project's own file system Oct 26, 2026
@kitlangton
kitlangton merged commit 7405f93 into dev Oct 26, 2026
14 checks passed
@kitlangton
kitlangton deleted the refactor/fileaccess-environment branch October 26, 2026 17:23
@kitlangton kitlangton changed the title refactor(core): folder-permission checks use the project's own file system fix(core): folder approvals use the project's own files, not this machine's disk Oct 26, 2026
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.

1 participant