.. and symlinks. This page explains the two layers that stop that and the one gap you should know about.
Layer A is a guard that runs before every read, edit, write, grep, find, ls or bash call. Layer B is the task file access that the real tools use.
Layer A: the tool-call guard
The guard denies four roots:~/.config/solana, ~/.ssh, ~/.oms and ~/.gnupg. In a session it also protects every pinned verifier file and the task’s .git.
.., ~ and symlinks
A rule on a path is easy to dodge if the path can be written a different way. So for path tools, OMS expands ~, makes the path absolute, then resolves it with realpath on the deepest existing ancestor and appends the missing tail. It compares the plain and real paths, plus lower-cased variants for case-insensitive volumes. That means a .. segment or a symlinked ancestor cannot walk around the rule, even for a file that does not exist yet.
Tests: yes. They cover .., symlinked ancestors, a read through a symlink into a denied root, and a .. escape into a denied sibling folder.
Layer B: task file access
The real file tools are the second line of defense, and they are strict about what they touch. They work only on regular files inside the task root, and they refuse a path that escapes the task through a symlink. Files open withO_NOFOLLOW, only regular files up to 64 KiB are allowed, and these names are refused anywhere in the path: .git, .oms, .keys and .env.agent. Writes under pinned verifier files or their ancestors are refused, including through a symlink alias. Directory listings skip symlinks.
Tests: yes, for symlinks, private names and read-only pinned files.
Not covered
Layer A checks~/.config/solana, ~/.ssh, ~/.oms and ~/.gnupg. Other key locations, for example ~/.aws, have no entry in this guard. The host approval prompt and the macOS sandbox do cover ~/.aws.