Uh oh!
There was an error while loading. Please reload this page.
fix(permission): read uses worktree-relative path patterns - #26527
Conversation
read evaluated permission rules against the absolute file path while
edit/write/apply_patch use path.relative(instance.worktree, filePath).
A user rule like "read": { "src/*": "deny" } silently failed to match
even though the equivalent "edit" rule worked.
Match the shape apply_patch already uses, including forward-slash
normalization. Updates the Windows assertion in read.test.ts and adds
three tests covering the relative pattern, slash normalization, and
end-to-end config rule matching.
Closesanomalyco#26524The following comment was made by an LLM, it may be inaccurate: Based on my search results, I found a potentially related PR: PR #24320: fix(read): match project-relative permissions This PR is directly related as it also addresses the The current PR (#26527) builds on this area by ensuring |
BennD
commented
May 10, 2026
Superseded by #26583, which shipped essentially the same fix. Closing. |
Issue for this PR
Closes#26524
Type of change
What does this PR do?
readwas evaluating permission rules against the absolute file path, whileedit/write/apply_patchalready use the worktree-relative path. So"read": { "src/*": "deny" }silently failed to match the same files that"edit": { "src/*": "deny" }would deny.This PR aligns
readwith the other file tools — emitspath.relative(instance.worktree, filepath).replaceAll("\\", "/")as the pattern. Same shapeapply_patchalready uses.Out of scope (tracked as follow-ups):
worktree === "/"makespath.relativeproduce nearly-absolute paths). Affects all relative-path tools, not justread.edit/write(currently masked byWildcard.matchdoing the same thing at match time). Will fold into a small helper-extraction refactor.How did you verify your code works?
bun typecheckfrompackages/opencode— cleanbun test test/tool/read.test.ts— 40/40 pass (3 new tests for the relative-pattern behavior, 1 updated Windows assertion)bun test test/permission test/tool— 365/365 pass"relative read patterns match worktree-relative deny rules from config"test directly feeds a config-derived ruleset throughPermission.evaluateagainst the patterns the read tool emits, assertingdeny.--singlebinary against a temp project containingpermission: { read: { "*": "allow", "src/*": "deny" }, edit: { "*": "allow", "src/*": "deny" } }. Before the fix, onlyeditdeniedsrc/secret.ts; after the fix, bothreadandeditdeny it as configured.Behavior change for users
Anyone who configured
readwith absolute paths (e.g."read": { "/home/me/proj/secrets/**": "deny" }) will need to rewrite as worktree-relative ("secrets/**": "deny"). This was the only way to make read rules match anything specific before this fix; the relative form matches the docs and how the other file tools work.Checklist