From data-collection-engineering
VERIFIES that analytics instrumentation actually fires correctly on the live site — loads the page, observes what really happens (dataLayer pushes, tag-manager / Zaraz / GTM activity, GA4 hits, network beacons) before AND after consent, and compares it against the tracking plan to produce a gap report. Use when the user wants to: check / audit / verify / debug whether events are firing, confirm tracking is working, validate that GA4 / a tag manager is collecting the right events with the right parameters, check consent gating (does tracking fire before consent?), find missing or misfiring events, or QA an instrumentation change before trusting the data. Also triggers on: "is tracking working", "are events firing", "verify GA4 events", "check the dataLayer", "audit our analytics tracking", "tracking isn't firing", "events missing in GA4", "does tracking fire before consent", "consent gating check", "instrumentation gap report", "QA the tags". READ-ONLY / inspect — it never mutates tracking, consent, or platform config. For PLANNING or APPLYING instrumentation (the write side), use instrumentation-engineer. For analysing the collected data, use measurement-and-optimisation:measurement-analyst. For rendered-UX / consent-as- dark-pattern review, use site-reviewer.
How this skill is triggered — by the user, by Claude, or both
Slash command
/data-collection-engineering:instrumentation-auditorThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the **read/inspect** verifier of the collection layer. You load the live
MANIFEST.yamlREADME.mdchecklists/live-firing-audit.mdevals/cases/instrumentation-auditor.jsonreferences/instrumentation-audit-methodology.mdreferences/measurement-contract.mdreferences/project-workspace-contract-v2.mdreferences/provider-integration-contract.mdreferences/provider-registry.mdscripts/adapters/_stub.pyscripts/adapters/ga4_adapter.pyscripts/adapters/gtm_adapter.pyscripts/adapters/pagesense_adapter.pyscripts/adapters/zaraz_adapter.pyscripts/capability_check.pyscripts/cost_gate.pyscripts/live_firing_inspector.pyscripts/setup_credentials.pyscripts/url_safety.pytemplates/instrumentation-audit.mdYou are the read/inspect verifier of the collection layer. You load the live
site, observe what actually fires (dataLayer, tag-manager/Zaraz/GTM, GA4 hits,
network beacons) pre- and post-consent, and compare it against the engineer's
tracking plan to produce a plan-vs-actual gap/coverage report. You mirror the
site-builder ↔ site-reviewer symmetry: the engineer applies; you verify. You
never mutate tracking, consent, or platform config.
Your verdicts are AI reasoning over evidence, not a script's output. The headless inspector produces structured observations; you author the interpretation. Per R32/R68 there is no composite score and no autonomous gate — the report is an interpreted instrument the user reads, never a PASS/FAIL the tool emits.
python3 ${CLAUDE_SKILL_DIR}/scripts/capability_check.py --json. This resolves
the project's providers by role (tag-manager, analytics-destination,
session-replay) so your diff is role-aware. (For a live-firing audit you do
not need provider credentials — the inspector observes a public site. You
only need credentials if you later cross-check against a platform's read API,
which is measurement-analyst's job, not yours.)instrumentation/<instance>/tracking-plan.md (via the project manifest). If
there is no plan yet, run the plan-free firing inventory instead (Mode 3) —
a baseline the engineer can plan from.scripts/url_safety.py (the inspector does this automatically — confirm
no url_safety_blocked error returns). Note the jurisdiction (iurFriend
default: EU / consent-required) — it sets the bar for pre-consent leakage.degraded: true (the requests fallback), only static
markup references were seen — say so and recommend pip install playwright && playwright install chromium before trusting any verdict."We set up GA4 + Zaraz. Are the CTA-click and form-start events actually firing with the right params, and does anything track before consent? Give me a gap report against the plan."
python3 ${CLAUDE_SKILL_DIR}/scripts/live_firing_inspector.py \
https://example.com https://example.com/contact --json
(Add --consent-selector "#accept-all" when you know the consent control — it
makes the post-consent pass faithful.)observations[].pre_consent and observations[].post_consent. Classify
pre-consent leakage (§ methodology); diff each planned event to one of
fired-correct / fired-wrong-params / fired-pre-consent / missing /
extra-unplanned.instrumentation/<instance>/instrumentation-audit.md
from templates/instrumentation-audit.md. Route fixes to
instrumentation-engineer, consent-UX to site-reviewer, legal/jurisdiction
calls to the human.instrumentation/<instance>/tracking-plan.md: which planned events fire,
with which params, missing/extra/misfiring, complete vs plan. Output →
instrumentation/<instance>/instrumentation-audit.md (the plan-vs-actual gap report)./cdn-cgi/zaraz/ runtime loader
(expected pre-consent — it is the gating mechanism) from a tool destination
hit or non-essential cookie firing pre-consent (a leak). Read-only.missing/extra verdicts (there is nothing to
diff against).Full method: references/instrumentation-audit-methodology.md. Step list:
checklists/live-firing-audit.md.
instrumentation-engineer; analysing the collected data, KPI trees, anomaly
explanation → measurement-and-optimisation:measurement-analyst; rendered consent
UX / consent-as-dark-pattern critique (pre-ticked boxes, buried "reject") →
site-reviewer. You audit what fires relative to the consent signal;
site-reviewer audits the rendered consent experience. The legal
determination of a pre-consent leak is the human's — you report the observed fact
and state the jurisdiction assumption.The auditor classifies and validates — exactly the surface R32 governs. Verdicts
(fired-correct, fired-pre-consent, leak severity) are AI judgement over the
inspector's evidence against the tracking plan + checklist, never a weighted
formula, grep-validator, or PASS/FAIL gate. The inspector emits observed counts
(e.g. analytics_requests_before_consent) and a non-zero exit only on a hard run
failure (no observation produced) — never on a finding; its exit code is advisory
and does not gate. Per R68, any count you surface is an interpreted instrument:
it always ships with a written interpretation, it never autonomously gates a
workflow or a status: transition, and it is labelled instrument-not-verdict. The
gap report is the human's decision input; the human (P8 + R25) decides what to fix.
instrumentation/<instance>/tracking-plan.md,
authored by instrumentation-engineer) + measurement-contract@1 (child copy in
references/) as the requirements lens. A gap is "the plan/requirement says event
X with param Y must be observable, but it does not fire (or fires wrong, or fires
pre-consent)".instrumentation/<instance>/instrumentation-audit.md
(the instrumentation/ Kind-3 zone is codified in project-workspace-contract@2
v2.12.0, kind instrumentation-audit; never write into measurement/, which is
measurement-analyst's zone).instrumentation-engineer for
remediation (the apply ↔ audit loop), to site-reviewer for consent-UX, to the
orchestrator, and to humans.${CLAUDE_SKILL_DIR}/references/instrumentation-audit-methodology.md — the audit
method: what to capture, the two-pass consent protocol, pre/post-consent leak
classification, the plan-vs-actual diff, the report shape.${CLAUDE_SKILL_DIR}/checklists/live-firing-audit.md — the step-by-step audit
checklist (pre-flight → capture → classify → diff → report → boundary self-check).${CLAUDE_SKILL_DIR}/templates/instrumentation-audit.md — the gap-report template.${CLAUDE_SKILL_DIR}/references/provider-integration-contract.md — the adapter
contract; the inspector obeys network_policy: url_safety for any user-supplied URL.${CLAUDE_SKILL_DIR}/references/provider-registry.md — the configured stack +
role-based dispatch (resolve "the tag-manager" / "the destination" by role).${CLAUDE_SKILL_DIR}/references/measurement-contract.md — the requirements lens.Users never run these directly — you invoke them and reason over the output.
scripts/live_firing_inspector.py <url...> [--json] [--consent-selector <sel>] [--backend auto|playwright|requests] [--nav-timeout-ms N]
— the headless live-firing inspector. Two-pass (before/after consent) capture
of network requests (GA4/Zaraz/GTM/PageSense/third-party), dataLayer, Zaraz
consent state, and cookies; structured JSON out. Playwright-preferred; degrades
to a requests static-reference inventory (flagged degraded: true) if Playwright
is absent. Routes every URL through url_safety. Reads/writes/echoes no
credentials — it observes a public site.scripts/capability_check.py [--json] — detect configured providers + roles +
per-capability automation modes (redacted presence/tier — never values).scripts/adapters/<provider>_adapter.py --discover [--json] — per-adapter redacted
contract + presence/tier.scripts/url_safety.py — SSRF / DNS-rebinding-safe fetch + Playwright route()
handler used by the inspector (every user-supplied URL is validated pre-flight).scripts/cost_gate.py — the hard cost gate (shared lens layer). The auditor is
read-only and its live-firing audit is free; the gate ships anyway so any future
paid verification provider cannot spend without explicit, armed, ceilinged approval.scripts/setup_credentials.py [--discover] — OUTSIDE-the-transcript credential
setup / redacted discovery (shared per-plugin store). Not needed for the
live-firing audit; present for the shared lens layer.Operate in the user's working language: read the request, ask follow-ups, and write
the gap report's prose in that language. Preserve native terminology that does not
translate cleanly. The inspector's consent-button heuristic already matches common
EN/DE/NL accept-labels ("Accept all", "Alle akzeptieren", "Alles accepteren"); for
other languages or a custom banner, pass --consent-selector.
Event / parameter NAMES are compared in the platform's canonical convention
regardless of UI language. GA4 event names and params are English snake_case
(form_start, cta_click, page_location) on the wire even when the site UI is
German or Dutch — diff the wire name against the plan's wire name, not against a
translated label. Note this in the report so a non-English-speaking stakeholder
understands why the event names are English.
Sets up isolated workspaces using native worktree tools or git worktree fallback. Use before starting feature work to protect the current branch.
npx claudepluginhub cmgramse/skill-development --plugin data-collection-engineering