You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of the Gmail epic. Follows the tool work — the plumbing has three new refusal states and none of them is currently expressible in the UI.
Why
Once Gmail can send, an owner has three independent switches to reason about, and today the console surfaces one of them:
Is Gmail connected — shown now, AccountConnections.tsx (Preferences → Connections), backed by GET /v1/email/status.
Does this agent have email permission — AgentState.permissions.email, enforced at lib/storage-tools.ts:553, toggled in Settings → Permissions & Connections.
Was the connection granted send scope — new, and unrepresented. A connection made before the send work exists carries gmail.readonly only.
An agent that fails to send because of (3) or (4) reports a tool refusal into a chat transcript. That is the wrong place for a state the owner has to change in Settings.
Scope
GET /v1/email/status gains canSend; AccountConnections.tsx shows Gmail as "connected — read only" with a Reconnect to allow sending action when the stored grant predates the send scope.
The instance Settings → Permissions & Connections block distinguishes "read my mail" from "send mail as me" rather than presenting one email switch, since they are now genuinely different powers.
The header comment at the top of lib/connectors/connected-accounts.ts currently argues at length that Gmail's tools: [] is "the point, not an omission". Once the connector carries declared tools that reasoning is half-true — it remains correct about find_confirmation_link and its permission-flag grant model, and becomes wrong as a statement about the connector. Rewrite it to say which of the two it means, or it will mislead the next reader exactly where the security argument lives.
platform-docs/connectors.md gets the Gmail entry: what it reads, what it can send, and the two gates.
Done when
every refusal the tools can produce corresponds to something the owner can see and change in the console, without reading a chat transcript to discover it
Part of the Gmail epic. Follows the tool work — the plumbing has three new refusal states and none of them is currently expressible in the UI.
Why
Once Gmail can send, an owner has three independent switches to reason about, and today the console surfaces one of them:
AccountConnections.tsx(Preferences → Connections), backed byGET /v1/email/status.AgentState.permissions.email, enforced atlib/storage-tools.ts:553, toggled in Settings → Permissions & Connections.gmail.readonlyonly.gmail([connectors] Connector consent + write-scope safety + admin visibility #90) — newly applicable oncescopes.writeflips totrue.An agent that fails to send because of (3) or (4) reports a tool refusal into a chat transcript. That is the wrong place for a state the owner has to change in Settings.
Scope
GET /v1/email/statusgainscanSend;AccountConnections.tsxshows Gmail as "connected — read only" with a Reconnect to allow sending action when the stored grant predates the send scope.lib/connectors/connected-accounts.tscurrently argues at length that Gmail'stools: []is "the point, not an omission". Once the connector carries declared tools that reasoning is half-true — it remains correct aboutfind_confirmation_linkand its permission-flag grant model, and becomes wrong as a statement about the connector. Rewrite it to say which of the two it means, or it will mislead the next reader exactly where the security argument lives.platform-docs/connectors.mdgets the Gmail entry: what it reads, what it can send, and the two gates.Done when