Skip to content

P0 filesystem: PathSandbox over isolated Codex LOCAL_FS - #51

Merged
novelKR merged 5 commits into
mainfrom
cursor/p0-filesystem
Sep 18, 2026
Merged

novelKR merged 5 commits into
mainfrom
cursor/p0-filesystem

Conversation

@novelKR

@novelKR novelKR commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add isolated crates/file-system (codespace-fs) wrapping Codex LOCAL_FS with sandbox: None, follow_symlinks: false, and a bounded walk. Public types stay CodeSpace-owned (Path / bytes / walk result / FsError).
  • Keep PathSandbox as the authorizer. That pre-check is not the I/O safety boundary. The shared primitive is Codex LOCAL_FS no-follow: Runner-owned read/find/rollback go through codespace-fs; apply_patch mutation uses crates/patchapply_patch_with_options on the same pin.
  • Typed FsError. After a failed no-follow I/O (ENOTDIR / ELOOP), the adapter inspects path components without following: an ancestor symlink is SymlinkRejected; a regular file in the middle is NotDirectory. The runner maps variants only.
  • For wire compatibility, NotFound / NotDirectory / generic Io currently collapse into PATH_ESCAPE. That is not the final filesystem taxonomy. Operator-registered workspace.root is the trust anchor; descendants under it are never followed.
  • Rollback snapshots restore through the same adapter, including parent mkdir and unix mode bits. Leaf/parent symlink-swap restore leaves outside files unchanged and reports incomplete. MCP read/find stay workspace-relative with frozen LIVE_TOOLS. No WIRE_PROTOCOL bump.
  • Intermediate directory symlink escapes are rejected. Walk caps match the pin (64 / 10_000 / 50_000). CI scans a narrow fs_key_allowed list and runs the adapter via --manifest-path. Remaining P0 subgraph: linux-sandbox → network.

Test plan

  • cargo test --manifest-path crates/file-system/Cargo.toml
  • cargo test -p codespace-runner --lib (including directory-symlink ancestor, find skip, rollback symlink-swap)
  • cargo test -p codespace-server --test read_find --test protocol_compat
  • ./scripts/check-no-model-deps.sh
  • python3 -B scripts/check_docs.py
  • CI rust job: fmt/clippy/test for crates/file-system plus workspace

Made with Cursor

novelKR and others added 5 commits September 18, 2026 13:02
Keep workspace authorization in PathSandbox, but use no-follow LOCAL_FS and a bounded walk so intermediate directory symlinks cannot escape the workspace.

Co-authored-by: Cursor <cursoragent@cursor.com>
PathSandbox stays authorization only. codespace-fs now owns SymlinkRejected
mapping and rollback mkdir/chmod so restore cannot follow a raced symlink.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep PATH_ESCAPE as a wire-compat collapse for NotFound/NotDirectory/Io,
and pin rollback against leaf and parent symlink swaps.

Co-authored-by: Cursor <cursoragent@cursor.com>
Directory symlinks become SymlinkRejected instead of PATH_ESCAPE, while
a regular file in the middle of a path stays NotDirectory.

Co-authored-by: Cursor <cursoragent@cursor.com>
rustix's Linux backend returns OPNOTSUPP for chmodat(SYMLINK_NOFOLLOW) even on regular files, so rollback chmod has to open the leaf with O_NOFOLLOW and fchmod the fd instead of using pathname chmod.

Co-authored-by: Cursor <cursoragent@cursor.com>
@novelKR
novelKR merged commit 5d12afd into main Sep 18, 2026
4 checks passed
@novelKR
novelKR deleted the cursor/p0-filesystem branch September 18, 2026 08:33
@novelKR novelKR mentioned this pull request Sep 18, 2026
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant