Skip to content

gads v3.9.1 — gads audit, register-gcp, mutate fix#2

Merged
talas9 merged 4 commits into
mainfrom
feature/gads-audit
Jun 25, 2026
Merged

gads v3.9.1 — gads audit, register-gcp, mutate fix#2
talas9 merged 4 commits into
mainfrom
feature/gads-audit

Conversation

@talas9

@talas9 talas9 commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • gads audit — new top-level command running a 12-section structural-compliance audit (0-100 score, A-F grade, per-section 0/50/100). Also available as gads analyze audit. Read-only; supports --format md|json.
  • 7 new gads analyze gap checksrsa-lengths, rsa-duplicates, dki, ad-schedule, attribution, budget-is, qs-distribution. All read-only, --json-ready, 24-48h attribution lag respected.
  • gads merchant register-gcp — do-it-for-you GCP project registration with Merchant Center (fixes GCP_NOT_REGISTERED). Calls developerRegistration:registerGcp. Proven live on Talas account. Merchant API v1 now LIVE.
  • P0 fix: ads_mutate resource canonicalization — snake_case resource names (e.g. campaign_criterion) now map to camelCase plural form (campaignCriteria) via _canonicalize_resource() + 21-entry _RESOURCE_ALIASES. Previously all snake_case names hit HTTP 404 silently. Unknown names raise ValueError before any HTTP call.
  • Docs — CHANGELOG, AGENTS.md, llms.txt, README (108→115 commands, 17→18 groups), CLAUDE.md taxonomy, RELEASE_NOTES v3.9.x section.
  • Tests — suite grew 174→231 (43 new check tests + 6 mutate URL construction tests); all pass offline.

Test plan

  • tools/gads --version returns 3.9.1
  • tools/gads audit --format json returns JSON with overall_score, grade, per-section scores
  • tools/gads analyze rsa-lengths --json exits 0
  • tools/gads merchant register-gcp --help exits 0
  • tools/gads mutate campaign_criterion '{}' --dry-run does not 404 (canonicalized to campaignCriteria)
  • tools/gads kb check exits 0
  • CI green on main after merge

talas9 added 4 commits June 24, 2026 17:45
A) New gads analyze subcommands (checks.py):
   - rsa-lengths: headline < 20 / description < 60 char flag (HIGH/MEDIUM/INFO)
   - rsa-duplicates: intra-RSA duplicate headline detection
   - dki: Dynamic Keyword Insertion presence/absence check
   - ad-schedule: per-campaign AD_SCHEDULE criteria coverage for SEARCH
   - attribution: Last-Click conversion attribution model flag
   - budget-is: search_budget_lost_impression_share > 10% per campaign
   - qs-distribution: QS sub-signal band distribution (post-click, creative, predicted CTR)

B) gads audit [--days N] [--format md|json] — top-level command wrapping
   the 12-section structural compliance audit (0/50/100 scoring, A-F grade).
   audit.py implements all 12 sections; render_audit supports md and json.

C) 43 new offline tests in tests/test_checks.py (217 total, all pass).
   41 tests in tests/test_audit.py (already staged from prior work).
   Version assertion updated to 3.9.0 in test_gads.py.

All checks: read-only GAQL, AED, window ends yesterday, --json + error
envelope per v3.8.2 standard. gads kb check exits 0. gads catalog --json
includes all new commands.
GAQL fixes (audit.py):
- keyword_view query: add campaign.status, ad_group.status,
  ad_group_criterion.status to SELECT (API v24 requires all WHERE
  fields to appear in SELECT)
- campaign_criterion negatives query: add campaign.status, type to SELECT
- campaign_asset sitelink query: switch campaign_asset.asset_type
  (non-selectable) to asset.type; add campaign.status to SELECT
  All three fixes verified live — gads audit now runs clean (56/100 grade C)

merchant register-gcp:
- gads_lib/merchant.py: mc_register_gcp() — POST to
  developerRegistration:registerGcp, json_body={"developerEmail": email},
  errors routed through request_json error envelope
- cli.py: gads merchant register-gcp --developer-email EMAIL [--account ID]
  [--json] — human + JSON output, validation guard for missing MC ID
- gads_lib/__init__.py: export mc_register_gcp
- kb/merchant-api.md: Developer Registration API reference section
- 8 new offline tests in TestMcRegisterGcp (225 total, all pass)
- CHANGELOG, AGENTS.md, llms.txt updated
…vent HTTP 404

P0 bug: passing snake_case resource names (e.g. campaign_criterion) to
ads_mutate() built URLs like /campaign_criterion:mutate which Google's
REST API returned as HTTP 404 HTML (not a JSON error), blocking all
account mutations via the generic mutate escape hatch.

Root cause: ads_mutate() used the resource_path string verbatim in the
URL. Google Ads REST API requires camelCase plural form (campaignCriteria),
not snake_case singular (campaign_criterion).

Fix: add _canonicalize_resource() with _RESOURCE_ALIASES dict (21 entries)
in ads.py. Snake aliases are mapped to canonical camelCase plural; unknown
snake names raise ValueError before any HTTP call; camelCase names pass
through unchanged.

Tests: 6 new tests in TestAdsMutateUrlConstruction covering the exact 404
regression (campaign_criterion→campaignCriteria URL), camelCase passthrough,
version+CID in URL, unknown-alias ValueError, alias map integrity.

Version: 3.9.0 → 3.9.1. Test suite: 217 → 231 (all passing).
- RELEASE_NOTES.md: add v3.9.x section (gads audit, 7 gap checks,
  merchant register-gcp proven live, mutate-404 fix); update title
  and command-count table through v3.9.1 (115 commands)
- README.md: bump command count 108→115; add Audit group row; expand
  Analyze row with 7 gap checks + audit subcommand; add register-gcp
  to Merchant row; group count 17→18
- CLAUDE.md: add audit top-level row to taxonomy table; expand analyze
  subcommands with 7 gap checks + audit; add register-gcp to merchant row
@talas9 talas9 merged commit f63033d into main Jun 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant