Audits 14 Gmail action rows from the [QA TESTING] Action To Scope Mapping — [DONE] Gmail sheet. Net effect: 6 actions changed, 5 actions reviewed but kept at master (after bugbot pass — see below), 3 need-review rows confirmed as no-op (stop_watch already correct, two sanity_* files are misfiled).
Every change is verified against the canonical Google API reference page for the action's actual _endpoints.
| Action | Edit |
|---|---|
createEmailDraft | drop gmail.readonly, gmail.send |
createLabel | drop gmail.readonly |
get_contacts | drop spurious contacts.other.readonly clause (endpoint is people.connections/list) |
send_draft | drop gmail.addons.current.action.compose (add-on contextual scope, doesn't authorize public REST) |
update_language_settings | drop mail.google.com/ (settings endpoints reject it) |
update_pop_settings | drop mail.google.com/ |
All edits stay in CNF ({all_of: [{any_of: [...]}]}) so they pass validate_scopes in mercury/tools/_base/action.py.
Cursor Bugbot flagged 4 issues on commit 1 (9693b02). All 4 were valid and have been fixed in commit 2 (e390e49):
| File | Severity | Issue | Fix |
|---|---|---|---|
update_draft.py | HIGH | Commit 1 added gmail.readonly + gmail.metadata per QA remark, but drafts.update doc lists only 3 scopes — a read-only token would pass Mercury then 403 at the PUT | Removed both; net effect for this action = no change vs master |
people.py (GetPeople) | HIGH | Commit 1 swapped contacts.other.readonly → directory.readonly per QA remark, but action actually calls people.get + otherContacts.list; the latter only accepts contacts.other.readonly | Reverted swap; no change vs master |
search_people.py | HIGH | Commit 1 replaced 2-clause AND with directory.readonly, but action calls people:searchContacts + otherContacts:search and directory.readonly authorizes neither | Restored 2-clause AND; no change vs master |
forward_message.py + replyToThread.py | MEDIUM | Commit 1 collapsed read-AND-send 2-clause structures into single any_of of send-class scopes, but both actions do internal messages.get/threads.get before sending; a gmail.send-only token would pass then 403 at the GET | Restored 2-clause AND on both; no change vs master |
Root cause: commit 1 followed QA's Doc remarks column verbatim without cross-checking each action's _endpoints list. Commit 2 fixes the 4 over-reach edits and keeps only the 6 changes where the QA remark genuinely aligned with the canonical docs.
GMAIL_STOP_WATCH — already correct per users.stop docs (4 scopes match exactly). QA hit a 404 on the doc URL they tried.GMAIL_CREATE_PROMPT_POST and GMAIL_SANITY_UPDATE_USER_ATTRIBUTES_VALUES — not Gmail actions at all. They call Sanity.io APIs (/agent/prompt, /.../users/.../attributes) with Sanity bearer auth. Empty _scopes is correct. They appear misfiled under apps/gmail/actions/ — worth a separate cleanup PR.ruff format + ruff check clean on all edited files (both commits)literal_eval of every changed _scopes confirms shape: {all_of: [{any_of: [...]}, ...]}developers.google.com/workspace/gmail/api/reference/rest/v1/… page for the action's actual endpoint(s)🤖 Generated with Claude Code