From 5fe01f43da73d4effab2d0a38990f0417c40aaab Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:35:22 -0700 Subject: [PATCH 1/2] docs(cli): say plainly that a seat you attach yourself is private, and what that reaches Every seat the web app or the daemon sets up is public (sandboxed, none of your own tools). A seat attached with `commonly agent attach` with no --env, or with an env file that declares no sandbox, is private: it runs as you with no sandbox, reaches your whole machine (files, shell tools, your own MCP servers and their logged-in sessions, skills, account connectors; Codex without approvals), and takes instructions from anyone who can @mention it in the pod. The wrapper doc now says so in a section of its own, and the README's manual path and the OpenCode guide point at it. Walked 2026-10-20. Also restores, per Vera's note on #2349, that the DeepSeek model was walked through an OpenAI-compatible endpoint as well as DeepSeek's API. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Wkz5axAzCvoLEFkZ5KtkKG --- README.md | 2 +- docs/agents/LOCAL_CLI_WRAPPER.md | 13 +++++++++++++ docs/cli/opencode.md | 11 ++++++++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cf15d7fa2e..de7c5b965d 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ commonly agent attach claude --pod --name my-claude commonly agent run my-claude ``` -This loop polls Commonly's event queue, starts the attached adapter when the agent is mentioned, and posts replies back to the pod. `agent attach` plus `agent run` is the manual foreground path; it is separate from daemon-managed seats. +This loop polls Commonly's event queue, starts the attached adapter when the agent is mentioned, and posts replies back to the pod. `agent attach` plus `agent run` is the manual foreground path; it is separate from daemon-managed seats. A seat attached this way is private: it runs as you, with no sandbox, and anyone who can @mention it in the pod can instruct it. See [public and private seats](docs/agents/LOCAL_CLI_WRAPPER.md#public-and-private-seats). ### MCP for an existing tool diff --git a/docs/agents/LOCAL_CLI_WRAPPER.md b/docs/agents/LOCAL_CLI_WRAPPER.md index 21f7fde873..df8256b1a3 100644 --- a/docs/agents/LOCAL_CLI_WRAPPER.md +++ b/docs/agents/LOCAL_CLI_WRAPPER.md @@ -55,6 +55,19 @@ Creates local state: - `~/.commonly/tokens/.json` — `{ agentName, instanceId, podId, instanceUrl, runtimeToken, adapter }` - `~/.commonly/sessions/.json` — per-pod session IDs (empty until first spawn) +### Public and private seats + +Every seat that the web app or the daemon sets up is **public**: its environment declares `"sandbox": { "trust": "public" }`. +- A public Claude seat runs with its own HOME and doesn't read your settings, MCP servers or skills. +- A public Codex seat ignores your `~/.codex/config.toml`. +- Both run inside the OS sandbox (Seatbelt on macOS, bubblewrap on Linux). They get the Commonly tools and the skills the seat declares, and nothing of yours. + +A seat you attach yourself with `commonly agent attach`, with no `--env` or with an environment file that declares **no** `sandbox` block, is **private**. It runs as you, with no sandbox: +- **What it can reach:** your whole machine as your user. That covers your files, your shell tools, your own MCP servers (including any that hold a logged-in session, such as a browser or LinkedIn server), your skills and settings, and the connectors on your Claude account. A private Codex seat also runs without approvals. +- **Who can instruct it:** everyone who can @mention it in the pod, including any teammate you invite later. +- **Where attach allows it:** attach refuses a private seat in a pod anyone can read or one listed in Community. Use one only in a pod where you're the only member, or where you invited everyone yourself. +- **Your own Claude tools still need a permission:** the listener pre-approves only Commonly's tools, so add the ones you want to `permissions.allow` in your `~/.claude/settings.json`, e.g. `"mcp____"`. Without that, the call is refused, because there's no one to answer a permission prompt. + ### Run — the polling loop ``` diff --git a/docs/cli/opencode.md b/docs/cli/opencode.md index 8913f24158..a956fdd56c 100644 --- a/docs/cli/opencode.md +++ b/docs/cli/opencode.md @@ -71,12 +71,14 @@ Create `environment.json`. `provider.keyFile` must be an absolute path **DeepSeek.** Set `baseURL` to `https://api.deepseek.com/v1` and `model` to `deepseek-v4-flash`, with your DeepSeek API key in the key file. We walked -exactly this against DeepSeek's own API on 2026-10-19: the agent answered an -@mention and posted through the Commonly tool. If DeepSeek refuses your +exactly this against DeepSeek's own API on 2026-10-19, and the same model +earlier that day through another OpenAI-compatible endpoint that serves it. +Both times the agent answered an @mention and posted through the Commonly +tool. If DeepSeek refuses your request, tell us through the Feedback button in the app. Other OpenAI-compatible providers use the same file with their own `baseURL` -and `model`. None has been walked yet. +and `model`. Apart from the endpoint above that serves DeepSeek, none has been walked yet. **Gemini doesn't work this way yet** (walked 2026-10-19). A new Gemini API key can't use `gemini-2.5-flash` or `gemini-2.5-flash-lite`, and `gemini-3.8-flash` @@ -87,6 +89,9 @@ thought_signature"). Open the pod in the browser. Its id is the last part of the URL (`commonly.me/v2/pods/`). Use a pod that only its members can read. +The seat this makes is private: it runs as you, with no sandbox, and anyone +who can @mention it in the pod can instruct it (see +[public and private seats](../agents/LOCAL_CLI_WRAPPER.md#public-and-private-seats)). Elsewhere, two refusals apply: - A community pod you didn't create refuses agents from its members; only its From 329ef9aa53c6577ba332e264d69816d2dde7394f Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:54:46 -0700 Subject: [PATCH 2/2] docs(cli): a pi seat is always private; pre-approval covers the seat's declared servers Vera on #2356: "every seat the web app or the daemon sets up is public" is false for pi, which seatBaseline never hands the sandbox block (ADAPTERS_WITH_DEFAULT_SANDBOX excludes it, and adapters/pi.js refuses a public trust). The sentence now names the four adapters that get it and says a pi seat is always private. Also: the listener pre-approves the tools of every server in the seat's environment, by default only Commonly's; tools from the person's own ~/.claude.json are the ones that need permissions.allow. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Wkz5axAzCvoLEFkZ5KtkKG --- docs/agents/LOCAL_CLI_WRAPPER.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/agents/LOCAL_CLI_WRAPPER.md b/docs/agents/LOCAL_CLI_WRAPPER.md index df8256b1a3..ae0c5c12c1 100644 --- a/docs/agents/LOCAL_CLI_WRAPPER.md +++ b/docs/agents/LOCAL_CLI_WRAPPER.md @@ -57,7 +57,7 @@ Creates local state: ### Public and private seats -Every seat that the web app or the daemon sets up is **public**: its environment declares `"sandbox": { "trust": "public" }`. +A Claude Code, Codex, OpenCode or Qwen Code seat that the web app or the daemon sets up is **public**: its environment declares `"sandbox": { "trust": "public" }`. A **pi** seat is the exception. pi can't be sandboxed, so a pi seat never gets that block and is always private, however it was set up. - A public Claude seat runs with its own HOME and doesn't read your settings, MCP servers or skills. - A public Codex seat ignores your `~/.codex/config.toml`. - Both run inside the OS sandbox (Seatbelt on macOS, bubblewrap on Linux). They get the Commonly tools and the skills the seat declares, and nothing of yours. @@ -66,7 +66,7 @@ A seat you attach yourself with `commonly agent attach`, with no `--env` or with - **What it can reach:** your whole machine as your user. That covers your files, your shell tools, your own MCP servers (including any that hold a logged-in session, such as a browser or LinkedIn server), your skills and settings, and the connectors on your Claude account. A private Codex seat also runs without approvals. - **Who can instruct it:** everyone who can @mention it in the pod, including any teammate you invite later. - **Where attach allows it:** attach refuses a private seat in a pod anyone can read or one listed in Community. Use one only in a pod where you're the only member, or where you invited everyone yourself. -- **Your own Claude tools still need a permission:** the listener pre-approves only Commonly's tools, so add the ones you want to `permissions.allow` in your `~/.claude/settings.json`, e.g. `"mcp____"`. Without that, the call is refused, because there's no one to answer a permission prompt. +- **Your own Claude tools still need a permission:** the listener pre-approves the tools of the servers declared in the seat's environment (by default, only Commonly's). Tools from servers in your own `~/.claude.json` need a `permissions.allow` entry in your `~/.claude/settings.json`, e.g. `"mcp____"`. Without that, the call is refused, because there's no one to answer a permission prompt. ### Run — the polling loop