Repository navigation
Conversation
…le write access projects.writeFile was missing from CLIENT_GUARDED_RPC_SCOPES, so its permissionAtom was always true and mobile's Save to workspace button stayed enabled for sessions without filesystem:write, failing only on the server. Move the entry into the client map that the server already spreads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — The client now requires file-write access before enabling workspace saves or sending write requests. Server permissions remain unchanged, so this prevents already-forbidden attempts without expanding access. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Note Written by Verified in a real dev environmentverified the shared permission guard at used repository playwright with exercised the actual shared nearby behavior passed: full-access web plan saving on both revisions, with the written file matching the plan; restricted-session markdown download; and another real codex turn on the pr returning 40 focused tests passed on blacksmith across before, main's existing web guard with the restricted connection: after, pr with the same plan and restricted scopes: full-access save on the pr, with actual file contents checked afterward: command and runtime transcript Not verifiednative ios/android button rendering and taps: this linux vm has no attached device or emulator. the shared command and permission used by the mobile card were exercised, but this is not native ui verification. desktop shell, other providers, relay/tunnel, and multi-environment file copying were not exercised. Merge with mainNote Written by merged current main into the branch at |
# Conflicts: # packages/client-runtime/src/state/commandPermissions.test.ts



Problem
On mobile, a connection without the
filesystem:writescope still shows an enabled "Save to workspace" button on a proposed plan. Tapping it, entering a path and saving fails only when the server rejects the write. The button should be off for that connection, as it already is on web.Change
projects.writeFilewas missing fromCLIENT_GUARDED_RPC_SCOPES, soclientRpcRequiredScopesreturned no scopes and the command'spermissionAtomwas always true. The mobile card reads that atom.projects.writeFile→filesystem:writeto the client map.RPC_REQUIRED_SCOPESspreads the client map, so the server still requires the same scope.projects.writeFilecase tocommandPermissions.test.ts, shaped like the OTLP grant test. It stays a separate case so it merges cleanly with feat(server): run CLIProxyAPI on an environment and manage its accounts in Settings #27388, which turns that test into a table. Once both land, it can become a row there.projectCommands.test.tsnow mounts the mocked session atom before setting it, as thecommandPermissions.test.tssetup does. With writes now checked on the client, an unmounted mock was dropped and the write test waited forever.Web already gates its Save to workspace and file editor on the same scope, so nothing changes there. Copying files when adding a project to another machine now fails on the client with "This connection requires filesystem:write" instead of on the server, and is reported in the same list.
Scope and approval
There is no issue. This is a one-entry fix of an obvious bug: AGENTS.md says protected client mutations go in
CLIENT_GUARDED_RPC_SCOPES, and this method was left out while the server already guarded it. Server authorization doesn't change. This PR adds no editing workflow and changes only whether the existing plan-save button is enabled.Prior PRs
#16927 by @camchis added the same map entry and a matching permission test as part of a mobile file editor. It was closed because the editor workflow needs approval in #16500. Closing it didn't touch this guard. This PR takes only the guard, for the save button mobile already ships.
Verification
vp test run packages/client-runtime/src/state/commandPermissions.test.ts: the newprojects.writeFilecase fails onmain(permissionAtomistruewith no grant) and passes with the fix. 19 tests pass.vp test run packages/client-runtime/src/state/projectCommands.test.ts apps/server/src/auth/RpcAuthorization.test.ts: all pass.vp run check:changed: format, lint, knip, typecheck and tests all pass.filesystem:write. Same session and thread in both states; only the two permission files differ between them.iOS before: Save to workspace is enabled.
iOS before: saving fails on the server.
iOS after: Save to workspace is dimmed and disabled.
Android before: Save to workspace is enabled.
Android before: saving fails on the server.
Android after: Save to workspace is dimmed and disabled.
The machine name is blanked out of the Android thread header.
Not checked:
Generated with Claude Opus 5.5 and GPT-6.1 Terra in T3 Code Nightly