test/changelog: follow up sandbox workspace mount fixes#32274
Conversation
PR SummaryLow Risk Overview Updates Written by Cursor Bugbot for commit 4f9ffea. This will update automatically on new commits. Configure here. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4f9ffea9cb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| bindArgs.push(args[i + 1]); | ||
| } | ||
| } | ||
| expect(bindArgs).toContain(expectedMainMount); |
There was a problem hiding this comment.
Strengthen mount-permission assertion in workspaceAccess table test
This assertion only checks that the expected mount string is present, but this test case builds cfg with createSandboxConfig([], undefined, workspaceAccess), which keeps the default custom bind "/tmp/workspace:/workspace:rw"; since custom binds are appended after the main mount in container creation, a ro/none case can still end up effectively writable while this test passes. As written, the regression test can miss exactly the permission regression it is meant to guard against.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| "uses expected main mount permissions when workspaceAccess=$workspaceAccess", | ||
| async ({ workspaceAccess, expectedMainMount }) => { | ||
| const workspaceDir = "/tmp/workspace"; | ||
| const cfg = createSandboxConfig([], undefined, workspaceAccess); |
There was a problem hiding this comment.
Test fixture adds conflicting rw bind overriding ro mount
Medium Severity
The new parameterized test calls createSandboxConfig([], undefined, workspaceAccess), where undefined for binds falls through to the default ["/tmp/workspace:/workspace:rw"]. The production code in createSandboxContainer first adds the main mount with the correct :ro suffix, then appendCustomBinds appends this default bind as -v /tmp/workspace:/workspace:rw for the same target. For the ro and none cases, the Docker args end up with both a :ro and a :rw bind for /workspace, with the :rw coming last. The toContain assertion passes because the :ro entry exists, but the regression test doesn't catch that a conflicting :rw mount undermines the read-only protection. Passing [] instead of undefined for binds would make this a proper regression test.
Additional Locations (1)
Greptile SummaryThis PR adds regression tests for the workspace mount permissions fix from #32227 across both sandbox create paths (
Confidence Score: 4/5
Last reviewed commit: 4f9ffea |
| it("mounts the main workspace read-only when workspaceAccess is none", async () => { | ||
| const cfg = buildConfig(false); | ||
| cfg.workspaceAccess = "none"; |
There was a problem hiding this comment.
Redundant workspaceAccess assignment
buildConfig(false) already returns a config with workspaceAccess: "none" (line 51 of this file), so the explicit reassignment on line 190 is a no-op. It creates a false impression that the test is changing something meaningful. The line can be removed without affecting behaviour.
| it("mounts the main workspace read-only when workspaceAccess is none", async () => { | |
| const cfg = buildConfig(false); | |
| cfg.workspaceAccess = "none"; | |
| const cfg = buildConfig(false); | |
| // workspaceAccess is already "none" from buildConfig |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/sandbox/browser.create.test.ts
Line: 188-190
Comment:
**Redundant `workspaceAccess` assignment**
`buildConfig(false)` already returns a config with `workspaceAccess: "none"` (line 51 of this file), so the explicit reassignment on line 190 is a no-op. It creates a false impression that the test is changing something meaningful. The line can be removed without affecting behaviour.
```suggestion
const cfg = buildConfig(false);
// workspaceAccess is already "none" from buildConfig
```
How can I resolve this? If you propose a fix, please make it concise.| it("mounts the main workspace read-only when workspaceAccess is none", async () => { | ||
| const cfg = buildConfig(false); | ||
| cfg.workspaceAccess = "none"; | ||
|
|
||
| await ensureSandboxBrowser({ | ||
| scopeKey: "session:test", | ||
| workspaceDir: "/tmp/workspace", | ||
| agentWorkspaceDir: "/tmp/workspace", | ||
| cfg, | ||
| }); | ||
|
|
||
| const createArgs = dockerMocks.execDocker.mock.calls.find( | ||
| (call: unknown[]) => Array.isArray(call[0]) && call[0][0] === "create", | ||
| )?.[0] as string[] | undefined; | ||
|
|
||
| expect(createArgs).toBeDefined(); | ||
| expect(createArgs).toContain("/tmp/workspace:/workspace:ro"); | ||
| }); | ||
|
|
||
| it("keeps the main workspace writable when workspaceAccess is rw", async () => { | ||
| const cfg = buildConfig(false); | ||
| cfg.workspaceAccess = "rw"; | ||
|
|
||
| await ensureSandboxBrowser({ | ||
| scopeKey: "session:test", | ||
| workspaceDir: "/tmp/workspace", | ||
| agentWorkspaceDir: "/tmp/workspace", | ||
| cfg, | ||
| }); | ||
|
|
||
| const createArgs = dockerMocks.execDocker.mock.calls.find( | ||
| (call: unknown[]) => Array.isArray(call[0]) && call[0][0] === "create", | ||
| )?.[0] as string[] | undefined; | ||
|
|
||
| expect(createArgs).toBeDefined(); | ||
| expect(createArgs).toContain("/tmp/workspace:/workspace"); | ||
| expect(createArgs).not.toContain("/tmp/workspace:/workspace:ro"); | ||
| }); |
There was a problem hiding this comment.
Missing ro workspace access test case
The docker path in docker.config-hash-recreate.test.ts uses it.each to cover all three valid SandboxWorkspaceAccess values (rw, ro, none), but this file only adds two tests — none and rw — leaving the ro case untested for the browser create path.
In browser.ts, both ro and none follow the same code branch (both map to :ro), so the none test provides implicit coverage. However, to stay consistent with the docker test and to guard against any future divergence in that branch, adding an explicit ro test here (or converting the two tests into an it.each over all three modes) would be a worthwhile follow-up.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/sandbox/browser.create.test.ts
Line: 188-225
Comment:
**Missing `ro` workspace access test case**
The docker path in `docker.config-hash-recreate.test.ts` uses `it.each` to cover all three valid `SandboxWorkspaceAccess` values (`rw`, `ro`, `none`), but this file only adds two tests — `none` and `rw` — leaving the `ro` case untested for the browser create path.
In `browser.ts`, both `ro` and `none` follow the same code branch (both map to `:ro`), so the `none` test provides implicit coverage. However, to stay consistent with the docker test and to guard against any future divergence in that branch, adding an explicit `ro` test here (or converting the two tests into an `it.each` over all three modes) would be a worthwhile follow-up.
How can I resolve this? If you propose a fix, please make it concise.

Follow-up to #32227 and #32217.
Scope:
src/agents/sandbox/browser.create.test.tssrc/agents/sandbox/docker.config-hash-recreate.test.tsWhy: