adding-warehouse-perso…
Sync columns from a synced data warehouse table onto PostHog person or group properties, so warehouse data becomes usable anywhere person and group properties…
Signals scout for Content Security Policy violations. Watches `$csp_violation` events for blocked-URL clusters, per-directive bursts, post-deploy regressions, and suspicious third- party domains.
$ npx -y skills add PostHog/ai-plugin --skill signals-scout-csp-violations --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/signals-scout-csp-violationsContext preview
The summary Claude sees to decide when to auto-load this skill.
Signals scout for Content Security Policy violations. Watches `$csp_violation` events for blocked-URL clusters, per-directive bursts, post-deploy regressions, and suspicious third- party domains.
name: signals-scout-csp-violations description: > Signals scout for Content Security Policy violations. Watches `$csp_violation` events for blocked-URL clusters, per-directive bursts, post-deploy regressions, and suspicious third- party domains. compatibility: > PostHog Signals agent (Claude sandbox). Read-only analytics + signal_scout_internal:write (scratchpad) + signal_scout_report:write (report channel), plus the analytics tools in the MCP tools section (execute-sql over `$csp_violation` events, read-data-schema, advanced-activity-logs-list). allowed_tools: - emit_report - edit_report metadata: owner_team: signals scope: csp_violations credits: pauldambra (PR #58596 — push-based CSP signal emission, encoded here as pull)
You are a focused CSP scout. Spot meaningful changes in this team's `$csp_violation` event stream — fresh blocked-URL domains, per-directive bursts, deploy-correlated page regressions, suspicious third-party scripts — and file reports only when a cluster clears the bar.
CSP violations are unusual on the noise/signal spectrum: a single user with a misbehaving browser extension can pollute thousands of reports, while a genuine script compromise might surface as five carefully crafted requests from a fresh domain. **Reach (distinct users + distinct documents) matters more than raw count**. Internalize that shape.
You author reports directly via the report channel (`scout-emit-report` / `scout-edit-report`): you've done the research, so you own each report 1:1 end-to-end rather than firing weak signals for a pipeline to cluster. The bar is correspondingly high — file a report only for an aggregated cluster (a fresh blocked domain, a standing enforced block, a deploy-correlated directive burst) you'd stand behind as a standalone inbox item a human will act on. A cluster the inbox already covers is an **edit only when something moved materially** — reach grew, disposition flipped to enforce, the verdict changed; a steady-state "still blocked, same reach" is a scratchpad re-confirmation, not an append every run. A **new blocked domain or directive is a new cluster and a new report**, even while a sibling domain's report is still open. The harness prompt carries the full report-channel contract (fields, status mapping, reviewer routing, dedupe, the `priority` / `repository` fields, and the edit rules), and `authoring-scouts` → `references/report-contract.md` is the deep reference (readable in-run via `skill-file-get`); this body adds only the CSP-specific framing — do not restate the generic mechanics. (Note: this surface has a companion **push** path that files raw per-fingerprint signals under `source_product=csp_reporting`; your own report-channel reports persist under `source_product=signals_scout`. Both live in the same inbox — see Decide for how they interact.)
If `$csp_violation` is absent from `top_events` or its `count` is at baseline (no fresh 24h activity, `recent_24h_count` ≪ `count / 7`), CSP reporting probably isn't where the signal is today. Cheap scratchpad entry + close out:
**Before** taking the baseline close-out, run the [standing enforced / first-party block](#standing-enforced--first-party-block-no-freshness-required) check below. "No fresh 24h burst" is **not** the same as "nothing to report" — a high-reach `disposition=enforce` cluster (or a first-party domain blocked at scale) is a live problem even when it's been steady for weeks, and it's exactly what a burst-only reading hides. Only close out as baseline once that check is also clean.
If `$csp_violation` is absent from `top_events` entirely (project doesn't ship a CSP reporting endpoint at all):
Close out empty in both cases. Re-running with the same key idempotently refreshes the timestamp — the entry stays until CSP reporting actually shows up, at which point the next run rewrites or deletes it.
Cycle between these moves; skip what's not useful.
Four cheap reads cold-start a run:
| Pattern | What it usually means | | ------------------------------------------------------- | ----------------------------------
Official PostHog plugin for AI clients. Access PostHog products directly from your AI coding tool.
Repo: PostHog/ai-plugin
Sync columns from a synced data warehouse table onto PostHog person or group properties, so warehouse data becomes usable anywhere person and group properties…
Analyze the most expensive users in AI observability and explain why they cost so much. Use when the user asks about top spenders, expensive users, per-user…
Analyze session replay patterns across experiment variants to understand user behavior differences. Use when the user wants to see how users interact with…
Split a completed PostHog task run into activity records — what the agent tried, whether it worked, what blocked it — and record each one through the…
Assesses what a page's heatmap is telling you and recommends concrete changes. Pulls click / rageclick / scroll-depth data for a URL, names the hot elements by…
Audit every endpoint in a PostHog project for staleness, failed materialisations, and unused materialised versions. Use when the user asks "what endpoints can…