feat(api): add Discovery-backed method access#867
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 22, 2026, 1:08 PM ET / 17:08 UTC. Summary Reproducibility: not applicable. this is a feature PR rather than a bug report. The PR body reports Review metrics: 3 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Keep the guarded implementation open for explicit maintainer acceptance of the generic Discovery caller and dynamic OAuth-scope model; if accepted, land it with the reported live Google proof and focused tests. Do we have a high-confidence way to reproduce the issue? Not applicable; this is a feature PR rather than a bug report. The PR body reports Is this the best way to solve the issue? Unclear as a product decision. The implementation is coherent for a guarded escape hatch, but VISION.md treats broad new API surfaces as discuss-first work. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 635f773788a8. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
6f6b5cf to
a618558
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a618558d87
ℹ️ 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".
| best := available[0] | ||
| for _, scope := range available[1:] { | ||
| if discoveryScopeScore(scope) < discoveryScopeScore(best) { | ||
| best = scope | ||
| } | ||
| } | ||
|
|
||
| return []string{best}, nil |
There was a problem hiding this comment.
Prefer granted Discovery scopes before narrow defaults
For accounts that already have one of the method's broader listed grants, this always requests the heuristically narrowest scope instead. For example, gog's default Gmail authorization stores gmail.modify, while a generic read such as gmail.users.labels.list will choose gmail.readonly; OAuth refreshes cannot add an ungranted scope string, so the call can fail even though the existing token has a valid listed scope. Please choose from the account's stored granted scopes when possible before falling back to the narrowest default.
Useful? React with 👍 / 👎.
| var value any | ||
| if err := json.Unmarshal(raw, &value); err != nil { | ||
| return fmt.Errorf("decode JSON response: %w", err) |
There was a problem hiding this comment.
Preserve large JSON numbers in API responses
When a Discovery call returns JSON containing numeric IDs or counters above JavaScript's safe integer range, this default json.Unmarshal converts them to float64 before re-encoding, so the output can silently round or rewrite values. The existing JSON transform path uses UseNumber; this path should do the same (or avoid decoding when no transform/wrapping is needed) to keep API results byte-accurate.
Useful? React with 👍 / 👎.
|
Landed as Verification:
Landing fixes: restricted authenticated targets and redirects to HTTPS Google API hosts, enforced explicit per-method command policy under runtime filters, blocked generic calls in baked safety profiles, and preserved JSON-shaped media byte-for-byte. |
Summary
Adds a Discovery-backed escape hatch for Google APIs and methods that do not yet have first-class gog commands:
gog api listgog api describe <api> <version> [method]gog api call <api> <version> <method>The implementation fetches Google's live Discovery document, resolves nested method IDs, validates path/query parameters, selects method-specific OAuth scope metadata, builds the REST request, and uses gog's existing account/client/token infrastructure.
Examples
Safety and contracts
--allow-writeand confirmation or--force.--dry-runemits the resolved method, HTTP verb, URL, and body presence without obtaining credentials or calling the target API.fieldsandaltare merged with method parameters; unknown parameters fail instead of disappearing silently.--scopepermits an explicit listed alternative.--wrap-untrustedbehavior.--wrap-untrustedis active.api.<method-id>permission for each generic method; baked safety-profile binaries rejectapi calland retain their static command boundary.api callintentionally grants a broader surface than narrow first-class commands. The README recommends first-class commands when available.Validation
make ciclawmac.local:gmail.users.labels.listfrom Google's live Discovery servicegmail.users.labels.createas POST and emitted a complete dry-run plan: exit 0; no label createdLive-test safety
Only the Gmail labels list read was executed. The mutation example used
--dry-run; no label or other Google data was created or changed.