Agents must now read client profiles before GTM work and write session logs after completing audits, tag changes, or validation — ensuring findings compound across sessions instead of being lost. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.2 KiB
description
| description |
|---|
| GTM QA - tag firing verification, trigger testing, naming conventions, cross-platform validation |
GTM Validator
Verify GTM implementations on live pages. Test triggers, validate dataLayer, check naming conventions.
Pre-Flight
BEFORE starting validation, read the relevant gotcha files at:
~/Project/dintel-gtm-agent/docs/log/gotcha/ (see README.md for index)
Priority reads per task:
- Trigger validation →
gotcha/triggers.md+gotcha/regex.md - Post-API-change QA →
gotcha/compilation.md - Variable inspection →
gotcha/variables.md
Triggers
- "validate tags", "QA GTM", "debug GTM"
- "naming conventions", "GTM best practice"
MANDATORY: Knowledge Base Read/Write
Before starting any validation or QA:
- Identify the target client from container ID or URL
- Read
knowledge-base/accounts/<client>/profile.md— naming conventions, known issues, platform stack - Read
knowledge-base/accounts/<client>/*.md— taxonomy defines expected events; naming fix plans reveal known violations - Skim
knowledge-base/logs/<client>/— past QA reveals recurring issues and known false positives
After completing validation, write a session log:
- Write to
knowledge-base/logs/<client>/YYYY-MM-DD-<description>.md - Include: date, container ID, pass/fail results, broken triggers (IDs), new naming violations
- Update
knowledge-base/accounts/<client>/profile.mdif you discovered persistent facts - See
AGENTS.mdfor full format template
Validation Modes
1. Tag Firing Verification
Navigate to page -> capture network requests -> compare expected vs actual tags
2. Trigger Condition Testing
Extract CSS selectors from trigger config -> test on live DOM -> flag 0-match (CRITICAL) or too-many-match (WARNING)
3. DataLayer Schema Validation
Check required fields per GA4 event (purchase: transaction_id, value, currency, items[])
4. Naming Convention Check
- Tags:
[Platform] - [event_name] [context] - Triggers:
[Type] - [description] Trigger - Variables:
[prefix] - [description](dlv, cjs, aev, jsv, URL, cookie, c)
5. Cross-Platform Event Mapping
Verify same action sends correct events to GA4, Meta, Google Ads, Kakao, Naver
6. QA Checklist
GTM snippet placement, dataLayer init, consent mode, ES5 compliance, sGTM endpoint
7. Version Comparison
Compare tag counts and changes between container versions
Gotchas (Hard-Won Lessons)
GTM Has Two Validation Layers — API CRUD vs Preview/Publish
GTM API validates schema only during create/update calls (field names, types, required params). Regex patterns are stored as opaque strings and never compiled at edit time. Preview/Publish performs full container compilation — all regex is compiled by Google RE2, all variable references resolved, cross-resource dependencies checked. A resource can pass API validation but break Preview.
Rule: After batch API changes, always attempt Preview before declaring success.
RE2 Does Not Support Lookaheads
GTM's regex engine (RE2) is linear-time and deliberately omits:
- Negative lookahead
(?!...) - Positive lookahead
(?=...) - Lookbehind
(?<=...)/(?<!...) - Backreferences
\1
Wrong (breaks at Preview/Publish with "내부 오류"):
^(?!.*(jamie\.clinic|tel:)).*$
Right — use separate conditions with negate parameter:
{
"type": "contains",
"parameter": [
{"type": "template", "key": "arg0", "value": "{{Click URL}}"},
{"type": "template", "key": "arg1", "value": "jamie.clinic"},
{"type": "boolean", "key": "negate", "value": "true"}
]
}
The negate Parameter Is Inside the Condition Array
GTM API negation is NOT a top-level field on the condition object — it's a {"type": "boolean", "key": "negate", "value": "true"} entry inside the condition's parameter array, alongside arg0 and arg1. Setting negate: true at the condition top level is silently ignored by the API.
RegEx Table Variable Column Names
The remm (RegEx Table) variable type uses key and value as column names in its map entries, NOT pattern and outputValue. Also requires {"type": "boolean", "key": "setDefaultValue", "value": "true"} to enable the default value.
Empty Template Fields Can Break Compilation
When creating linkClick triggers via API, setting waitForTags, checkValidation, waitForTagsTimeout via the parameter array sometimes produces empty top-level template stubs ({"type": "template"} with no value). These empty stubs can cause compilation issues. Either set them correctly at the top level or omit them and let GTM use defaults.
Timer Triggers Cannot Use customEventFilter
Timer triggers fire on gtm.timer — they are NOT custom events. Use filter (not customEventFilter) to add page-level conditions to timer triggers. customEventFilter is only valid on customEvent type triggers.
Colon : Is Not Allowed in Trigger Names
GTM trigger names cannot contain :. Use - or other separators instead.
Key Rules
- Test on LIVE published version (not preview, unless debugging)
- Test on both desktop and mobile viewports
- CSS selector triggers = fragility risk; recommend adding IDs
- Document every test with screenshots/network evidence