emrg: enforce workspace-write boundary in write/edit tools - #1092
Merged
Conversation
…-09-01T15:10:23) The write/edit tools only boundary-checked the 'read-only' sandbox tier; under 'workspace-write' they skipped validation entirely, letting an agent write/edit anywhere outside the session cwd while the bash tool correctly blocked absolute-path escapes — a tool asymmetry. Add check_workspace_write() in bash_tool (mirroring the bash tool's workspace-write semantics: protected daemon files and ~/.emrg blocked, absolute paths outside the workspace root blocked, OS temp allowed, relative paths assumed in-workspace), and call it from the write/edit tools' workspace-write branch. Pass the ORIGINAL file_path so relative paths keep the in-workspace assumption. Fixes the asymmetric hole and aligns with dsh's writableRoots single-source + tool-symmetry design. +7 tests (write/edit positive & negative states), Agent.md doc-count 1200->1207.
argszero
commented
Sep 1, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 20260901-154922
argszero
commented
Sep 1, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 20260901-155702
argszero
commented
Sep 1, 2026
argszero
left a comment
Owner
Author
There was a problem hiding this comment.
✅ LGTM — cycle 20260901-160415
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
writeandedittools only boundary-checked the read-only sandbox tier (check_read_only_file_write); under workspace-write they skipped validation entirely. An agent in a workspace-write session could write/edit anywhere outside the session cwd (e.g. a sibling directory), while thebashtool correctly blocked absolute-path escapes — a tool asymmetry that a workspace-write session could use to escape its sandbox.Root cause
write_tool.py:70/edit_tool.py:85only called the read-only check whensandbox == "read-only". Theworkspace-writetier fell through to the rawpath.write_text/path.editwith no boundary validation.args["workspace"]= session cwd (daemon.py:2762), but the write/edit tools never consumed it under workspace-write.Fix
Add
check_workspace_write()inbash_tool.pymirroring the bash tool's workspace-write semantics, and call it from both tools' workspace-write branch:~/.emrg/config.toml,emrgd.token,tasks.yml,projects.yml,rants.jsonl) → blocked~/.emrgitself → blocked (would erase the daemon's data dir)The tools now pass the original
file_path(not the resolved one) so relative paths keep the in-workspace assumption — resolving a relative path against the daemon cwd would wrongly classify it as absolute-outside-workspace.This aligns with dsh's
writableRootssingle-source + tool-symmetry design (bash and fs write tools share one writable-root boundary).Testing
+7tests covering write/edit positive & negative workspace-write states (outside-workspace block, inside-workspace allow, OS-temp allow, protected-config block)./Users/argszero/Downloads/1writing to sibling/Users/argszero/Downloads/2/poem.txt) — now correctly blocked.pytest tests/→ 1207 passed, 1 skipped.1200 → 1207.