agentsclimarketplace

Verify pixels

Skill wjb127/claude-skills/verify-pixels/skills/verify-pixels

Claude Code skills built while shipping real client websites — image generation without API keys, per-project memory, evidence-producing QA.

Install
npx -y skills add wjb127/claude-skills --skill verify-pixels

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 13 days oldThe repository was created 13 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Verify that ad and analytics pixels actually fire — GA4, Meta, GTM, TikTok, Naver, Kakao — by driving a real browser, then produce a screenshot + network evidence package. Includes an auto-fix loop for the common install errors. 광고 픽셀·GA4 설치 검증 + 클라이언트 제출용 증거 패키지 생성.

SKILL.md

27.9 KB, ~9.8k tokens by cl100k_base, as published. Nobody here has run it

verify-pixels — 광고 픽셀 / GA4 / GTM 설치 검증 + 증거 확보

광고/분석 스크립트가 실제로 동작하는지 Playwright로 검증하고, 클라이언트 반박 못할 수준의 스크린샷 + 네트워크 증거 패키지를 생성한다.

호출 예시:

  • /verify-pixels — 프로젝트 자동 분석 + 전체 검증
  • /verify-pixels --url https://example.com — 외부 URL 검증
  • /verify-pixels meta only — Meta Pixel만
  • /verify-pixels ga4 only — GA4만
  • /verify-pixels --quick — 핵심 페이지 1개만 (PageView 검증)

2026년 컨텍스트 (반드시 인지)

AI 생성 트래킹 코드의 흔한 오류 (50%+ 실패):

  1. 잘못된/플레이스홀더 Pixel ID, Measurement ID (GA_MEASUREMENT_ID, XXXXXXXX 그대로 남음)
  2. UA(Universal Analytics) 패턴을 GA4에 적용 (event-based 모델 무시)
  3. Config 태그보다 Event 태그가 먼저 fire (session_id, traffic source 누락)
  4. Consent Mode V2 신호 누락 — 2026년 EEA/UK 강제. ad_storage/analytics_storage/ad_user_data/ad_personalization 4개 신호
  5. PageView 중복 발사 (gtag + GTM 둘 다 설치, fbq 두 번)
  6. 일부 페이지만 설치 (홈만 OK, /pricing 누락 패턴)
  7. Custom parameter를 Custom Dimension으로 등록 안 함 → 리포트에 안 보임
  8. Measurement Protocol에 debug_mode / engagement_time_msec 누락
  9. CAPI(Conversions API) 미연동 — 클라이언트만 → iOS/AdBlock에서 20~35% 누락
  10. CAPI/Pixel event_id 불일치 → 중복 카운트 → 데이터 인플레이션

Pixel Helper 그린 ≠ "트래킹 완료":

  • Pixel Helper는 "브라우저에서 요청 떠남"까지만 보장
  • "Meta 서버 수신 + 처리 + 어트리뷰션 사용"은 Events Manager Test Events에서만 확인
  • 따라서 검증은 3계층 필요: 네트워크 캡처 + Pixel Helper/Tag Assistant + Test Events/DebugView

에이전시 감사 통계: 초기 셋업 40~60%가 파라미터 문제. CPA 2~3배 악화.


검증 대상 (자동 감지)

다음 도메인/패턴을 자동 매칭:

플랫폼요청 패턴확인 항목
GA4google-analytics.com/g/collect, analytics.google.com/g/collect, region1.google-analytics.comtid (G-XXXXX), en (event name), cid, sid, dl (page location), tid format G-
Google Adsgoogleadservices.com/pagead/conversion, googleads.g.doubleclick.netconversion label, value, currency
GTMgoogletagmanager.com/gtm.js?id=GTM-GTM-XXXXX ID format
Meta Pixelfacebook.com/tr, facebook.com/tr/, connect.facebook.net/en_US/fbevents.jsid (15~16자리), ev (event name), cd[content_ids], cd[value], eid (event_id)
TikTokanalytics.tiktok.com/api/v2/pixel, analytics.tiktok.com/i18n/pixel/events.jssdkid, event, properties
Naverwcs.naver.net/wcslog.js, wcs.naver.com/wcslog.gif_nasa, _naa
Kakaot1.daumcdn.net/kas/static/kp.js, analytics.ad.daum.netkakaoPixelId
Microsoftbat.bing.com/bat.js, bat.bing.com/action/0ti (Pixel ID)
Hotjarstatic.hotjar.com/c/hotjar-siteId
Clarityclarity.ms/tag/projectId

실행 흐름

Step 1 — 프로젝트 / URL 분석

경우 A: 프로젝트 컨텍스트 있음 (pwd로 감지)

  • Next.js: next.config.js + app/layout.tsx / pages/_app.tsx / pages/_document.tsx 검사
  • Astro: astro.config.mjs + 레이아웃 컴포넌트 검사
  • 정적 HTML: <head> 검사
  • 배포 URL 감지: vercel.json, .vercel/project.json, README

경우 B: URL만 주어짐 (--url 옵션)

  • 직접 fetch해서 HTML 분석

Step 2 — 정적 코드 검사 (Source Audit)

다음을 grep / 정규식으로 확인:

# GA4 Measurement ID 패턴
grep -rE "G-[A-Z0-9]{8,12}" src/ public/ 2>/dev/null

# GTM Container ID
grep -rE "GTM-[A-Z0-9]{6,8}" src/ public/ 2>/dev/null

# Meta Pixel ID (15~16자리 숫자)
grep -rE "fbq\\(['\"]init['\"], ['\"][0-9]{14,17}['\"]" src/ public/ 2>/dev/null

# 플레이스홀더 잔존 확인 (절대 안 됨)
grep -rE "GA_MEASUREMENT_ID|YOUR_PIXEL_ID|XXXXXXXX|G-XXXXXXX|GTM-XXXXXX" src/ public/

# Consent Mode V2 신호
grep -rE "consent\\s*\\(\\s*['\"]default['\"]|ad_storage|analytics_storage" src/ public/

경고 발동 조건:

  • 플레이스홀더 그대로 남아있으면 즉시 RED 플래그
  • GA4 ID가 UA-로 시작 (Universal Analytics 패턴) → RED
  • gtag + GTM 동시 발견 → 중복 위험 YELLOW
  • Consent Mode V2 신호 누락 (EEA 타겟이면 RED)

Step 3 — Playwright 동적 검증

3-1. 네트워크 요청 캡처 스크립트

import { test, expect, Page } from '@playwright/test';
import fs from 'node:fs';
import path from 'node:path';

const TRACKERS = {
  ga4: /google-analytics\.com\/g\/collect|analytics\.google\.com\/g\/collect|region\d+\.google-analytics\.com/,
  gtm: /googletagmanager\.com\/gtm\.js/,
  googleAds: /googleadservices\.com\/pagead\/conversion|googleads\.g\.doubleclick\.net/,
  metaPixel: /facebook\.com\/tr|connect\.facebook\.net\/en_US\/fbevents\.js/,
  tiktok: /analytics\.tiktok\.com/,
  naver: /wcs\.naver\.(net|com)/,
  kakao: /t1\.daumcdn\.net\/kas|analytics\.ad\.daum\.net/,
  bing: /bat\.bing\.com/,
};

interface TrackerHit {
  platform: string;
  url: string;
  method: string;
  status: number;
  timestamp: number;
  params: Record<string, string>;
  postData?: string;
}

async function captureTrackers(page: Page, route: string, eventDir: string) {
  const hits: TrackerHit[] = [];

  page.on('request', async (req) => {
    const url = req.url();
    for (const [platform, pattern] of Object.entries(TRACKERS)) {
      if (pattern.test(url)) {
        const u = new URL(url);
        const params: Record<string, string> = {};
        u.searchParams.forEach((v, k) => { params[k] = v; });
        hits.push({
          platform,
          url,
          method: req.method(),
          status: 0,
          timestamp: Date.now(),
          params,
          postData: req.postData() || undefined,
        });
      }
    }
  });

  page.on('response', (res) => {
    const url = res.url();
    const hit = hits.find(h => h.url === url && h.status === 0);
    if (hit) hit.status = res.status();
  });

  await page.goto(route, { waitUntil: 'networkidle' });
  await page.waitForTimeout(2000); // 지연 fire 픽셀 대비 (예외적 허용)

  // 스크린샷 + 네트워크 패널 저장
  await page.screenshot({ path: path.join(eventDir, `${route.replace(/\//g, '_')}.png`), fullPage: true });
  fs.writeFileSync(path.join(eventDir, `${route.replace(/\//g, '_')}.json`), JSON.stringify(hits, null, 2));

  return hits;
}

3-2. 검증 assertion (Happy/Sad/Bad/Ugly)

test.describe('GA4 검증', () => {
  test('Happy: 홈에서 page_view 1회만 fire', async ({ page }) => {
    const hits = await captureTrackers(page, '/', './evidence/ga4-home');
    const pageViews = hits.filter(h => h.platform === 'ga4' && h.params.en === 'page_view');
    expect(pageViews.length, '중복 PageView 발견').toBe(1);
    expect(pageViews[0].status, 'GA4 응답 코드 200/204 아님').toBeLessThan(300);
    expect(pageViews[0].params.tid, 'GA4 Measurement ID 누락').toMatch(/^G-[A-Z0-9]+$/);
  });

  test('Sad: 모든 핵심 페이지에 GA4 설치됨', async ({ page }) => {
    const routes = ['/', '/about', '/pricing', '/contact'];
    for (const r of routes) {
      const hits = await captureTrackers(page, r, `./evidence/ga4-${r.replace(/\//g, '_')}`);
      const found = hits.find(h => h.platform === 'ga4');
      expect(found, `${r}에 GA4 미설치`).toBeDefined();
    }
  });

  test('Bad: Measurement ID에 플레이스홀더 없음', async ({ page }) => {
    const hits = await captureTrackers(page, '/', './evidence/ga4-id-check');
    const ga4 = hits.find(h => h.platform === 'ga4');
    expect(ga4?.params.tid).not.toMatch(/XXXX|MEASUREMENT_ID|YOUR_ID/i);
  });
});

test.describe('Meta Pixel 검증', () => {
  test('Happy: PageView fire + 200 응답', async ({ page }) => {
    const hits = await captureTrackers(page, '/', './evidence/meta-home');
    const pv = hits.filter(h => h.platform === 'metaPixel' && /PageView/i.test(h.params.ev || ''));
    expect(pv.length, 'Meta PageView 없음').toBeGreaterThanOrEqual(1);
    expect(pv.length, 'Meta PageView 중복').toBeLessThanOrEqual(1);
    expect(pv[0].params.id, 'Pixel ID 누락').toMatch(/^\d{14,17}$/);
    expect(pv[0].status).toBeLessThan(300);
  });

  test('Bad: Lead event는 폼 제출에서만 fire (페이지 로드에선 X)', async ({ page }) => {
    const hits = await captureTrackers(page, '/', './evidence/meta-lead-not-on-load');
    const leadOnLoad = hits.find(h => h.platform === 'metaPixel' && /Lead/i.test(h.params.ev || ''));
    expect(leadOnLoad, 'Lead가 페이지 로드에서 잘못 fire됨').toBeUndefined();
  });
});

test.describe('Consent Mode V2 (EEA 대상)', () => {
  test('초기 consent default 신호 존재', async ({ page }) => {
    let consentDefault = false;
    page.on('console', msg => {
      if (msg.text().includes('consent') && msg.text().includes('default')) consentDefault = true;
    });
    await page.addInitScript(() => {
      const orig = (window as any).gtag;
      (window as any).gtag = function(...args: any[]) {
        if (args[0] === 'consent' && args[1] === 'default') console.log('[consent default]', JSON.stringify(args[2]));
        return orig?.apply(this, args);
      };
    });
    await page.goto('/', { waitUntil: 'networkidle' });
    // Consent Mode V2는 페이지에 consent_state HTML element 또는 dataLayer 검사
    const dataLayer = await page.evaluate(() => (window as any).dataLayer || []);
    const hasConsent = dataLayer.some((e: any) => e[0] === 'consent' || e.event === 'consent');
    expect(hasConsent || consentDefault, 'Consent Mode V2 신호 없음').toBe(true);
  });
});

3-3. 시나리오별 이벤트 검증

핵심 사용자 흐름을 자동 실행 + 그 시점 네트워크 캡처:

시나리오트리거기대 이벤트
홈 진입page.goto('/')GA4 page_view, Meta PageView (각 1회)
폼 제출getByTestId('submit').click()GA4 generate_lead, Meta Lead
결제 완료/order/success 진입GA4 purchase (transaction_id 포함), Meta Purchase (value/currency 포함)
전화 클릭tel: 링크 클릭GA4 phone_click (커스텀)
카카오 클릭채널 링크 클릭GA4 kakao_click (커스텀)

각 시나리오에서:

  • 네트워크 요청 캡처 → JSON 저장
  • 풀 페이지 스크린샷 → PNG
  • 콘솔 로그 캡처 → 에러 0개여야 함

Step 4 — 외부 검증 도구 스크린샷 (선택, 수동 안내)

Pixel Helper / Tag Assistant는 Chrome 확장이라 Playwright headless에서 안 됨. 다음 중 하나:

옵션 A — Playwright headed + 확장 로드 (실험적):

const ctx = await chromium.launchPersistentContext('/tmp/profile', {
  headless: false,
  args: [
    '--disable-extensions-except=/path/to/pixel-helper',
    '--load-extension=/path/to/pixel-helper',
  ],
});

옵션 B — 사용자에게 명확한 가이드 (권장): 사용자에게 다음 안내 + 스크린샷 받기:

Pixel Helper / Tag Assistant 검증은 자동화 어려움 (Chrome 확장 + Facebook 로그인 필요).
다음 단계로 직접 확인 후 스크린샷 저장해줘:
1. Chrome에서 https://<url> 접속
2. Meta Pixel Helper 클릭 → 사이드 패널 캡처
3. ./evidence/manual/pixel-helper.png 로 저장
4. GA4 DebugView (https://analytics.google.com → 관리자 → DebugView) 열고
   해당 사이트에서 클릭 몇 번 한 뒤 실시간 이벤트 캡처
5. ./evidence/manual/ga4-debugview.png 로 저장

Step 5 — 증거 패키지 생성 (HTML 리포트)

tracking-audit-report-YYYYMMDD.html 생성:

프로젝트 루트/
└── tracking-audit-report-20260522.html
└── evidence/
    ├── ga4-home.png             (풀페이지 스크린샷)
    ├── ga4-home.json            (캡처된 네트워크 요청)
    ├── ga4-pricing.png
    ├── meta-home.png
    ├── meta-home.json
    ├── consent-check.png
    └── manual/
        ├── pixel-helper.png     (사용자 제공)
        └── ga4-debugview.png    (사용자 제공)

HTML 리포트 구조 (consulting-report 스킬 디자인 시스템 활용):

  • 헤더: 프로젝트명, 검증일, 대상 URL
  • 요약 대시보드: 검증 항목 N개 / 통과 X / 경고 Y / 실패 Z
  • 항목별 상세 카드: 각 트래커별로
    • 상태 뱃지 (GREEN/YELLOW/RED)
    • 발견된 ID (G-XXXXXXX 등)
    • fire된 이벤트 목록 + 응답 코드
    • 스크린샷 썸네일 (클릭하면 lightbox)
    • 네트워크 요청 raw payload (접을 수 있게)
  • 이슈 리스트: 발견된 모든 문제 + 권장 조치
  • 클라이언트 응답 스크립트: "여기 사진처럼 적용 완료되었습니다" 포함 텍스트

Step 6 — 클라이언트 반박 방지 응답 스크립트 생성

리포트 마지막에 다음 형태 텍스트 자동 생성 (이모지 금지, 글로벌 규칙):

--
안녕하세요, 광고 픽셀 / GA4 설치 검증 완료되어 회신드립니다.

검증 도메인: https://<url>
검증 일시: 2026년 5월 22일 14:30

[1] Google Analytics 4
- Measurement ID: G-XXXXXXX
- page_view 이벤트 정상 발사 (응답 200)
- 검증 페이지: 홈 / 소개 / 가격 / 문의 (총 4개) 모두 정상
- 첨부: evidence/ga4-home.png, evidence/ga4-pricing.png

[2] Meta Pixel
- Pixel ID: 1234567890123456
- PageView 이벤트 정상 발사 (응답 200)
- Lead 이벤트는 폼 제출 시에만 발사되도록 정확히 설정됨
- 첨부: evidence/meta-home.png

[3] Google Tag Manager
- Container ID: GTM-XXXXXX
- 모든 페이지에 정상 로드됨

추가로 GA4 DebugView 및 Meta Events Manager Test Events 화면도
첨부드렸으니 함께 확인 부탁드립니다.

혹시 추가 검증이 필요한 페이지나 이벤트가 있으시면 말씀 주세요.
--

Step 7 — 자동 수정 루프 (Auto-Fix Loop)

검증 → 실패 발견 → 수정 → 재검증을 모든 항목이 GREEN이 되거나 escape 조건에 걸릴 때까지 반복한다.

루프 정책

최대 반복: 5회 (--max-loops 옵션으로 조정 가능, 기본 5)
타임아웃: 전체 30분 (--timeout 옵션)
변화 없음 감지: 직전 2회와 동일한 진단 결과 → escape (무한 루프 방지)
사용자 확인 트리거: 자동 수정 불가 영역 발견 시 즉시 사용자에게 보고

자동 수정 가능 / 불가 분류

자동 수정 가능 (LOOP) — 코드/설정 파일 수정으로 해결:

진단자동 수정 액션
플레이스홀더 ID 잔존 (G-XXXXXXX)사용자에게 실제 ID 1회 질문 → 모든 파일 일괄 치환
UA- 패턴 잔존grep으로 위치 찾아 GA4 패턴으로 교체 (gtag config)
gtag + GTM 동시 설치둘 중 하나 제거 (GTM 우선 유지, gtag 직접 호출 제거)
일부 페이지에 스크립트 누락공통 레이아웃(app/layout.tsx, BaseLayout.astro 등)으로 이동
Consent Mode V2 신호 누락gtag('consent', 'default', {...}) 4신호 head 최상단 삽입
PageView 중복 firefbq('init') 중복 호출 제거
Lead가 페이지 로드 시 잘못 fire트리거를 button.click 이벤트로 이동
GTM trigger가 DOM Ready코드 내 GTM dataLayer push 시점 조정
셀렉터 취약성 (data-testid 없음)해당 element에 data-testid 추가

자동 수정 불가 (ESCAPE) — 사용자/외부 시스템 필요:

진단안내 액션
GA4 Measurement ID 자체를 모름사용자에게 "Analytics 관리자 → 데이터 스트림에서 G-... 가져와줘"
Meta Pixel ID 자체를 모름사용자에게 "Events Manager → 데이터 소스에서 픽셀 ID 가져와줘"
GA4 DebugView 확인 필요수동 가이드 + 스크린샷 요청
Events Manager Test Events 확인수동 가이드 + 스크린샷 요청
Custom Dimension 등록"GA4 관리자 → 맞춤 정의에서 등록 필요" 안내
Key Event(전환) 마크"GA4 관리자 → 이벤트에서 generate_lead 전환 토글" 안내
CAPI 서버사이드 미연동"별도 작업 필요. 권한과 액세스 토큰 받아서 진행" 안내
광고 매니저 어트리뷰션"캠페인 보고서에서 확인 필요" 안내
도메인 verification"Facebook Business Manager에서 처리" 안내

루프 알고리즘 (의사 코드)

async function autoFixLoop(maxLoops = 5, timeoutMs = 30 * 60 * 1000) {
  const startTime = Date.now();
  const history: DiagnosisSnapshot[] = [];

  for (let loop = 1; loop <= maxLoops; loop++) {
    console.log(`\n=== Loop ${loop}/${maxLoops} ===`);

    if (Date.now() - startTime > timeoutMs) {
      report('TIMEOUT', '전체 타임아웃 30분 초과 — 사용자 확인 필요');
      break;
    }

    // 1. 검증 실행 (Step 3 그대로)
    const diagnosis = await runFullVerification();
    history.push(diagnosis);

    // 2. 모두 GREEN이면 완료
    if (diagnosis.allGreen()) {
      report('SUCCESS', `${loop}회 루프 만에 모든 검증 통과`);
      return;
    }

    // 3. 변화 없음 감지 (직전 2회와 동일)
    if (history.length >= 3) {
      const last3 = history.slice(-3);
      if (isSameDiagnosis(last3[0], last3[1]) && isSameDiagnosis(last3[1], last3[2])) {
        report('STUCK', '직전 2회 루프와 동일한 진단 결과 — 자동 수정 한계, 사용자 개입 필요');
        await dumpDiagnosis(diagnosis);
        break;
      }
    }

    // 4. 자동 수정 가능 항목 분리
    const fixable = diagnosis.issues.filter(i => i.category === 'AUTO_FIXABLE');
    const escape = diagnosis.issues.filter(i => i.category === 'ESCAPE');

    // 5. ESCAPE 항목이 있으면 즉시 사용자에게 보고
    if (escape.length > 0) {
      report('USER_INPUT_REQUIRED', escape);
      const userResponse = await askUser(escape);  // 1회 질문, 답 받아서 계속
      if (!userResponse) break;
      applyUserInput(userResponse);  // ID 등 사용자가 제공한 값 적용
    }

    // 6. 자동 수정 적용
    if (fixable.length === 0 && escape.length === 0) {
      report('UNKNOWN_FAILURE', '진단은 실패 표시인데 수정 액션이 없음 — 사용자 확인');
      break;
    }

    for (const issue of fixable) {
      console.log(`  → 수정 시도: ${issue.title}`);
      const fixResult = await applyAutoFix(issue);
      if (!fixResult.success) {
        console.log(`  ✗ 수정 실패: ${fixResult.reason}`);
      }
    }

    // 7. 빌드 & 배포 (코드 수정이 있었으면)
    if (fixable.some(f => f.requiresRebuild)) {
      console.log('  → 빌드 + 배포 진행');
      await runBuild();
      await runDeploy();
    }
  }

  // 루프 종료 — 최종 리포트 생성
  await generateFinalReport(history);
}

루프 실행 중 사용자 보고 (1줄씩, 글로벌 규칙)

[Loop 1/5] 검증 시작 → 실패 4건 발견
  ✗ GA4: Measurement ID에 'G-XXXXXXX' 플레이스홀더 잔존
  ✗ Meta: PageView 중복 fire (2회)
  ✗ Consent Mode V2 신호 없음
  ⚠ /pricing 페이지에 GTM 누락 (ESCAPE 아님, 자동 수정 가능)

  사용자에게 필요한 정보:
  → 실제 GA4 Measurement ID 알려줘 (예: G-ABC1234567)

[사용자 응답 받음: G-ABC1234567]

[Loop 1/5] 자동 수정 적용 중
  → src/lib/analytics.ts: G-XXXXXXX → G-ABC1234567 치환
  → public/index.html: fbq('init') 중복 1개 제거
  → src/layouts/Base.astro: Consent Mode V2 default 신호 추가
  → src/pages/pricing.astro: GTM 스니펫 누락 → 공통 레이아웃으로 이동

[Loop 1/5] 빌드 + 배포 진행
  → pnpm build 성공
  → Vercel 배포 성공 (URL: ...)

[Loop 2/5] 재검증 시작 → 실패 1건 남음
  ✗ Meta: Lead 이벤트가 페이지 로드 시점에 잘못 fire

[Loop 2/5] 자동 수정 적용
  → src/components/ContactForm.tsx: fbq('Lead') 위치를 onSubmit 핸들러로 이동

[Loop 2/5] 빌드 + 배포 → 성공

[Loop 3/5] 재검증 시작 → 모든 검증 GREEN
✓ 완료. 총 3회 루프, 12분 22초 소요.

Escape 조건 상세

다음 중 하나 발생 시 루프 중단 → 사용자에게 명확히 보고:

  1. MAX_LOOPS 도달: "5회 루프 후에도 N건 미해결. 마지막 진단 결과 첨부."
  2. TIMEOUT: "30분 초과. 진행 상태 첨부."
  3. STUCK: "직전 2회 루프와 동일한 결과 = 자동 수정 한계. 진단 + 시도한 액션 첨부."
  4. USER_INPUT_REQUIRED: ID/토큰/외부 서비스 설정 필요 — 사용자 응답 대기.
  5. BUILD_FAILED: 빌드 실패 → 수정 코드 자체에 문제. 변경 사항 revert 후 사용자 보고.
  6. DEPLOY_FAILED: 배포 실패 (Vercel git author 등) → 별도 가이드로 안내.

안전장치 (반드시 지킴)

  • 자동 수정 전 git stash: 매 루프 시작 시 git stash push -m "verify-pixels-loop-N" → 롤백 가능
  • 빌드 실패 시 즉시 revert: pnpm build 실패 → git stash pop 또는 git checkout 으로 직전 상태로
  • 프로덕션 직배포 금지: 코드 수정 → 빌드 → preview 배포 → 검증 → 통과 시에만 prod (또는 사용자 컨펌)
  • 3회 같은 파일 수정 감지 시 escape: 동일 파일을 3번 이상 수정해도 통과 못하면 사용자 개입
  • DROP/DELETE SQL 자동 실행 금지 (글로벌 규칙)
  • 외부 서비스 API 호출 자동화 금지: GA4/Meta 대시보드 변경은 사용자만

사용자 옵션

/verify-pixels --loop                  # 자동 수정 루프 활성 (기본은 비활성, 진단만)
/verify-pixels --loop --max-loops 3    # 최대 3회로 제한
/verify-pixels --loop --no-deploy      # 빌드만, 배포는 사용자가
/verify-pixels --loop --interactive    # 매 수정마다 사용자 컨펌 (안전 모드)
/verify-pixels --loop --dry-run        # 진단 + 수정 액션 출력만, 실제 변경 X

최종 리포트에 추가 섹션

루프가 끝난 후 HTML 리포트에 다음 섹션 추가:

<section class="loop-history">
  <h2>자동 수정 루프 히스토리</h2>
  <div class="timeline">
    <div class="loop-step">
      <div class="loop-num">Loop 1</div>
      <div class="loop-found">발견: 4건</div>
      <div class="loop-fixed">수정: 3건 자동 + 1건 사용자 응답</div>
      <div class="loop-build">빌드/배포: 성공 (1분 23초)</div>
    </div>
    <!-- ... -->
  </div>
  <div class="loop-summary">
    총 N회 루프, X분 Y초 소요. 최종 상태: 전체 통과
  </div>
</section>

정직성 원칙

"통과"라는 표현 금지, 정확하게 표기

정확한 보고부정확한 보고
"page_view 1회 정상 fire, 200 응답""GA4 정상"
"Pixel Helper 미검증 (확장 자동화 불가) — 수동 확인 가이드 첨부""Meta Pixel 완벽 설치"
"클라이언트 사이드만 검증됨. CAPI 서버사이드는 별도 확인 필요""트래킹 완료"
"EEA 대상이면 Consent Mode V2 신호 추가 필요"(누락)

Pixel Helper "Green" 의미 정확히 표기

리포트에 다음 문구 포함:

Pixel Helper의 녹색 체크는 "브라우저에서 요청이 떠났음"을 의미하며, "Meta 서버가 이벤트를 수신/처리/어트리뷰션에 사용함"을 보장하지 않습니다. 서버 수신 검증은 Events Manager Test Events에서, 어트리뷰션 적용은 캠페인 보고서에서 별도 확인이 필요합니다.

CAPI / 서버사이드 미검증 명시

이 스킬은 클라이언트 사이드만 검증. CAPI(Conversions API), 서버사이드 GTM, Measurement Protocol은 별도 도구 필요. 리포트 푸터에 명시.


흔한 함정 (체크리스트로 변환)

검증 시 다음을 자동 확인:

  • Measurement ID / Pixel ID 가 플레이스홀더가 아님 (XXXXXXX, YOUR_ID 등 X)
  • GA4 ID가 G-로 시작 (UA-면 Universal Analytics 잔존, RED)
  • PageView 정확히 1회 fire (2회 이상이면 중복 설치)
  • gtag + GTM 동시 존재하지 않음 (있으면 중복 위험 경고)
  • 모든 핵심 페이지(홈/가격/소개/문의)에 트래커 로드
  • 응답 코드 200/204
  • Lead/Purchase 이벤트가 페이지 로드 시점에 잘못 fire되지 않음
  • Consent Mode V2 default 신호 존재 (EEA 타겟이면)
  • event_id 가 Pixel 이벤트에 포함됨 (CAPI 연동 시)
  • 콘솔 에러 0개 (fbq, gtag 관련 에러 없음)
  • GTM trigger가 "All Pages" 또는 "Page View" 사용 (DOM Ready / Window Loaded X)
  • purchase 이벤트에 transaction_id, value, currency 모두 포함
  • generate_lead 이벤트가 GA4에서 key event(전환)로 마크됨 (수동 확인 안내)

Page Object 패턴 (재사용)

// tests/tracking/lib/tracker-recorder.ts
export class TrackerRecorder {
  hits: TrackerHit[] = [];

  attach(page: Page) {
    page.on('request', (req) => { /* ... */ });
    page.on('response', (res) => { /* ... */ });
  }

  byPlatform(platform: string) { return this.hits.filter(h => h.platform === platform); }
  byEvent(name: string) { return this.hits.filter(h => h.params.en === name || h.params.ev === name); }
  hasNoDuplicates(platform: string, event: string) { /* ... */ }
  saveEvidence(dir: string, label: string) { /* json + png */ }
}

금지 사항

  • ❌ "트래킹 완벽 설치" / "100% 정상" 같은 단정적 표현 (CAPI/서버 미검증 상태에서)
  • ❌ Pixel Helper 그린만 보고 OK 판정
  • ❌ 홈 1페이지만 검증하고 "전체 사이트 OK"
  • ❌ Consent Mode V2 누락된 EEA 사이트를 PASS 처리
  • ❌ 스크린샷 없이 텍스트로만 보고 (클라이언트 반박 방지가 핵심 목적)
  • ❌ 플레이스홀더 ID(G-XXXXXXX 등)를 발견하고도 정상 처리
  • ❌ 외부 URL 검증 시 사용자 동의 없이 무한 페이지 크롤링
  • ❌ 자동 수정 루프에서 --max-loops 초과 강행
  • ❌ 빌드 실패한 코드 변경을 그대로 둔 채 다음 루프 진행 (반드시 revert)
  • ❌ 자동 수정 루프에서 GA4/Meta 대시보드 등 외부 서비스 변경 시도
  • ❌ 사용자 응답 대기 중 임의로 다음 루프 진행
  • ❌ STUCK 상태(같은 진단 3회)에서 같은 수정 액션 반복

사용자 시나리오별 출력

시나리오 1: 클라이언트가 "픽셀 안 깔린 것 같아요" 라고 함

/verify-pixels --url <클라이언트URL> --quick → 결과: HTML 리포트 + 스크린샷 4~5장 → 응답 스크립트:

--
첨부 사진처럼 Meta Pixel(ID: ...)과 GA4(ID: G-...)가 정상 적용되어
PageView 이벤트가 200 응답으로 발사되고 있음을 확인했습니다.

evidence/meta-home.png — 네트워크 탭에서 facebook.com/tr 요청 200 응답
evidence/ga4-home.png — google-analytics.com/g/collect 요청 200 응답
evidence/source-code.png — HTML 소스에 픽셀 코드 정상 포함

혹시 광고 매니저 화면에서 이벤트가 안 보이신다면 Aggregated Event
Measurement 우선순위 설정 또는 Consent Mode 영향일 수 있으니
추가 확인 도와드리겠습니다.
--

시나리오 2: 신규 배포 직후 자체 검증

/verify-pixels → 결과: 전체 페이지 × 전체 트래커 매트릭스 → 실패 항목만 추출해서 수정 후 재실행

시나리오 3: 특정 이벤트(Lead, Purchase)만 검증

/verify-pixels --event Lead --flow "/contact → 폼 작성 → 제출" → 결과: 폼 제출 시점 네트워크 캡처 + payload 검증


출력 톤 (글로벌 규칙 준수)

  • 한국어, 반말, 간결
  • 클라이언트 응답 스크립트 부분만 정중한 비즈니스 한국어 (이모지 금지)
  • 진행 중 업데이트 1줄씩
  • 작업 완료 후 ntfy 알림 (Title: "트래킹 검증 완료 — G-XXX / Pixel XXX 정상")

Gives 0 of the 12 instructions most quality gates skills give in ~9.8k tokens

Counted across 1,195 of the 2,094 authors here whose files we hold, read 2026-08-06

  • read the output and check the exit codein 55 of 1195, across 14 files
  • verify requirements using a line-by-line checklistin 53 of 1195, across 12 files
  • identify the verification command proving the claimin 53 of 1195, across 12 files
  • run the full verification commandin 51 of 1195, across 11 files
  • verify output confirms the claimin 49 of 1195, across 10 files
  • check version control diff after agent delegationin 45 of 1195, across 5 files
  • state claim with evidencein 43 of 1195, across 3 files
  • run the test suitein 32 of 1195, across 24 files
  • keep state in memory by defaultin 27 of 1195, across 6 files
  • make prototype runnable with one commandin 26 of 1195, across 5 files
  • detect the package manager from lockfilesin 24 of 1195, across 5 files
  • produce a verification reportin 23 of 1195, across 12 files

Said here and by no other author read

  • capture network requests with playwright
  • run static code inspection for tracking ids
  • check for placeholder ids remaining
  • trigger events for core user flows
  • generate client response script
  • run the auto-fix loop on failures

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.