Session Overview

Sam requested a full environment for Google Ads campaign management, modeled after the Technical SEO environment that was already built. Originally scaffolded in workspace-v2, the environment was later relocated to Repos/sail-googleads as part of the workspace-v2 retirement project. The goal was to take the negative keyword dedup cleanup (which had been running as a standalone scheduled task and was 99.1% complete, 2,694 of 2,718 duplicates removed) and house it inside a proper self-contained workstation with its own skills, hooks, commands, agents, and automation loops.

The reference architecture was the Technical SEO Environment Build documented at Session: Technical SEO Environment Build, 2026-04-17. Every structural decision in this build mirrors that pattern: same hook types, same dedup guard logic, same file conventions, same definition-of-done requirements.

The session also transitioned the existing scheduled task (google-ads-neg-cleanup) from an hourly one-time cleanup (with a static list of duplicate IDs) to a weekly Monday 6am maintenance scan that pulls live data from the Google Ads MCP and runs a fresh dedup analysis.

What Was Accomplished

1. Full Environment Scaffolding

Created the complete directory structure at /Users/samaguiar/Documents/Projects/Repos/sail-googleads/environments/google-ads/ with all standard workspace-v2 folders: .claude/ (skills, hooks, commands, agents), inputs/, outputs/ (audits, reports, fix-lists, deltas), logs/, state/, handoffs/, reference/, scripts/.

2. CLAUDE.md (Core Environment Config)

Path: /Users/samaguiar/Documents/Projects/Repos/sail-googleads/environments/google-ads/CLAUDE.md

Covers: scope definition, account details (Customer ID 3813916687, Campaign ID 23723841732, MCP server ID a41e699d-7a46-4477-8cdf-d4b51b52a4ba), MCP-first rule (all reads and writes go through the Google Ads MCP), MCP usage (Adspire unlimited MAX plan, batch keyword ops in groups of 100 for payload manageability), connect-before-speculating data hierarchy, destructive action guardrails (approval required for pauses, budget changes, keyword removals, targeting changes, new campaigns), tooling map (6 env-native skills + 6 shared skills), skill dedup discipline (4-layer system), 4 automation loops with schedules, ad copy brand rules, definition of done, file location conventions, and firm rules.

3. settings.json

Path: /Users/samaguiar/Documents/Projects/Repos/sail-googleads/environments/google-ads/.claude/settings.json

Environment variables (GADS_ENV_ROOT, GADS_CUSTOMER_ID, VAULT_ENV), permissions (allow vault reads, scripts, hooks; deny credential writes, destructive deletes; ask for git push/commit), all 6 hook types wired to shell scripts, skill roots with dedup enforcement (onConflict: "block"). Note: The Google Ads MCP is a Cowork connector (server ID a41e699d-7a46-4477-8cdf-d4b51b52a4ba), not a local MCP server, so it is NOT listed in settings.json mcpServers. It is referenced by ID in CLAUDE.md and skill procedures.

4. Six Hook Scripts

All under .claude/hooks/:

session-start.sh: Loads vault.env, checks for GOOGLE_ADS_DEVELOPER_TOKEN, CLIENT_ID, CLIENT_SECRET. Runs dedup guard refresh. Reports neg-dedup progress from state file. Checks data freshness across inputs/.

skills-dedup-guard.sh: Python-based engine scanning 4 skill roots (env-local, Projects/Skills, Downloads/skills/user, Cowork sessions). Parses SKILL.md frontmatter for names, sha256 conflict detection. Check and refresh modes. Exits 2 on conflict. Identical logic to technical-seo env.

pre-tool-use.sh: Blocks destructive recursive deletes at root/home.

pre-file-write.sh: Intercepts SKILL.md writes, checks skills-lock.json, blocks if skill name exists in another root.

post-tool-use.sh: Logs all Google Ads MCP calls (tools containing "a41e699d") to dated log file. Refreshes dedup lock after skill file writes.