PostHog
@PostHog Organization
Public Skills
merging-prs
by PostHog
Merge a PR into master through the Trunk merge queue and babysit it until it lands. Enqueue with a /trunk merge comment, then watch trunk merge status and the PR state until it is MERGED or the queue kicks it out, reporting Trunk's own reason for the terminal transition. Use when asked to merge a PR, "merge when ready", "land it", "ship it", to merge a whole stack (comment on the top PR — the queue merges it and every layer below atomically), to get a PR approved by stamphog (MCP review request first, stamphog label as the fallback), or to babysit/watch a PR through the queue. Never use gh pr merge in this repo — the queue is the only path into master.
reviewing-with-coderabbit
by PostHog
Run a CodeRabbit review over the branch from the terminal, with the coderabbit CLI, and record the pass in the PR description. Before gh pr create or a requested branch review, first check POSTHOG_TASK_RUN_ID and CI: a cloud or CI task skips this skill without a CLI probe or user message. Otherwise, use this skill to check cr and its authentication, and offer setup or skip when a person can answer. Run the review once per branch. Never substitute an agent review. Trigger terms: coderabbit, cr review, local review, self-review, review my branch, pre-PR review.
django-migrations
by PostHog
Django migration patterns and safety workflow for PostHog. Use when creating, adjusting, or reviewing Django/Postgres migrations, including non-blocking index/constraint changes, multi-phase schema changes, data backfills, migration conflict rebasing, and product model moves that require SeparateDatabaseAndState. Also use for any deletion or removal of a model, table, column, product, or app — including deleting migration files or retiring a feature — even when no migration is written.
building-product-empty-states
by PostHog
Guide for adding a product setup empty state — the skippable first-run screen a product scene shows until real data arrives, built on the shared ProductEmptyState component. Use when adding an empty state or first-run/setup screen to a product scene, declaring emptyState on a SceneExport, writing a product setup-status detection logic, building an animated example-data preview widget, or deciding between the scene-level ProductEmptyState gate and an inline ProductIntroduction panel. Covers the productSetupStatusLogic single-layer contract, real-data detection rules, local-only skip semantics, wizard commands, and design tokens.
debugging-mcp-analytics
by PostHog
Debug, support, and build PostHog MCP Analytics — product analytics for MCP servers (the @posthog/mcp and posthog.mcp SDKs plus the mcp_analytics product). Use when MCP analytics data looks wrong or missing ("events aren't showing", "intent clusters are empty", "sessions are missing", "per-tool numbers look wrong"), when writing queries over $mcp_* events by hand, or when doing feature work on the SDKs, the dashboard and its query runners, the self-instrumented MCP server, the wizard mcp-analytics install command, or the in-app onboarding. Covers the repo map, the $mcp_* vocabulary and where each property comes from, the rules that silently corrupt metrics when ignored, the end-to-end pipeline and where each stage breaks, and which repo to change. For reading the data rather than fixing it, prefer the exploring-mcp-* and improving-mcp-tools skills.
triaging-merge-queue-failures
by PostHog
Decision procedure for a PR that failed or was removed from the Trunk merge queue: classify the kick (superseded by a newer commit, not mergeable, a gate that failed on a cancelled run, real failure, one-off flake, or repo-wide flaky/infra issue) and take the matching action (wait, hold and fix, requeue once, or escalate instead of spam-retrying). Use when a PR is kicked from the queue, Trunk reports a failed queue attempt on a PR, someone asks "why was my PR removed from the queue" or "should I requeue", or when running as the scheduled merge queue triage sweep. Trigger terms: merge queue kicked, removed from queue, queue failure, requeue, trunk merge failed. Operators setting up the automation itself: see references/routine-setup.md.
authoring-ci-workflows
by PostHog
Use when adding or editing a GitHub Actions workflow, composite action, or reusable workflow under .github/ — new CI jobs, triggers, matrices, checkout/clone tuning, action pinning, GitHub App token auth, concurrency groups, timeout-minutes, paths filters, caching, or runner choice. Covers PostHog's workflow-authoring conventions and the reasons behind them: the 500-runs/10s dispatch cap, shallow vs full clone, per-SHA push concurrency, dedicated App-token rate-limit buckets, and fork-safe secrets on a public repo. Points to the linters (bin/hogli lint:workflows, actionlint) that enforce the mechanical rules, and to the narrower skills for production deploys, secrets, and Depot runners. Not for debugging red CI (use debugging-ci-failures) or wiring a new secret end to end (use managing-github-actions-secrets).
debugging-ci-failures
by PostHog
Debugs failing GitHub Actions CI runs for PostHog PRs, commits, and branches, and answers broad CI-health questions ("is CI red?", "is master green today?", "what's broken right now?"). Use when the user asks why CI is red, asks for the current CI or master status, or mentions a failing check, GitHub Actions run, Depot runner, Depot CI run, workflow, job, shard, merge queue kick, flaky test, lint failure, typecheck failure, snapshot diff, migration check, generated types drift, or skills build failure. Interactive runs start with the hogli ci:insights digest (cross-run CI history from engineering analytics), then use read-only inspection, failure classification, the smallest local reproduction with hogli, and safe reporting without rerunning CI or posting to GitHub. Running unattended as the "Master-red diagnosis" workflow: see references/master-red-incident.md for its sandbox-compatible first step.
django-startup-time
by PostHog
Keep heavy imports off the django.setup() path that every process (web, celery, temporal, migrate, shell, CI) pays for. Use when touching AppConfig.ready(), wiring signal receivers, editing the lazy API router (posthog/api/rest_router.py or its init.py shim), deferring a heavy import or profiling import time (importtime, hothog), when the startup-import-budget guard fails, or when merging master into a long-lived branch that made the router lazy.
gating-sensitive-actions
by PostHog
'Use when deciding whether an endpoint, settings section, or UI flow should require recent authentication (re-auth), when adding TimeSensitiveActionPermission or its exemptions (time_sensitive_allow_if_only_fields, time_sensitive_exclude_actions, time_sensitive_allow_actions), when wrapping a page or settings section in TimeSensitiveAuthenticationArea, when an API read returns secret material, or when a write fails with sensitive_action_required_reauth. Carries the product decision: reads stay open, only sensitive writes need a fresh session, and the backend enforces it; organization settings are the one area gated on navigation. Covers how the frontend opens the re-auth modal and retries the failed request, and how to test a new gate. Trigger terms: re-auth, reauthenticate, reauthentication, sensitive session, fresh session, sudo mode, step-up, TimeSensitiveActionPermission, TimeSensitiveAuthenticationArea, sensitive_action_required_reauth.'
improving-mcp-tools
by PostHog
Run an improve-my-MCP campaign: an autoresearch-style loop that measures the MCP agent experience with the eval harness, picks the highest-impact tool problem from production data, makes one bounded fix, and keeps it only if before/after scores improve. Use when asked to "improve my MCP", run an MCP improvement campaign, fix tool discoverability or descriptions based on evidence, or prepare an eval-backed PR for a tool change. Every shipped change must carry eval evidence; guardrails below are hard rules.
developing-subscriptions
by PostHog
Guides PostHog engineers through subscription product changes. Use when changing subscription resource types, destinations, schedules, delivery workflows, retry or automatic disable behavior, permissions, limits, AI summaries, AI prompt reports, delivery history, subscription APIs, MCP tools, or subscription management UI. Not for configuring an existing subscription through MCP.
authenticating-to-clickhouse
by PostHog
Authenticate a new or changed service to ClickHouse with the rotating ch-podauth ServiceAccount token instead of a static password. Use when adding a service, sidecar, or container that reads or writes ClickHouse, adding a new ClickHouseUser, or hand-building a ClickHouse pool or client for a custom timeout or setting. Covers the token-aware default path (sync_execute, get_client), the rule that a custom pool must pass credential_provider or it silently stays on the static password, wiring the username so the user does not fall back to the default user, and the deploy-side companion in the charts repo. Not for converting an already-deployed user off a static password.
implementing-mcp-tools
by PostHog
'Guide for exposing PostHog product endpoints as MCP tools. Use when creating new or updating API endpoints, adding MCP tool definitions, scaffolding YAML configs, or writing serializers with good descriptions. Covers the full pipeline from Django serializer to generated TypeScript tool handler.'
optimizing-clickhouse-and-hogql-queries
by PostHog
Workflow for optimizing ClickHouse and HogQL queries. Use when a HogQL query, query runner, insight, or report is too slow; when a hand-written ClickHouse query (via sync_execute or in a migration) is too slow; when ClickHouse times out or hits memory limits; when investigating a slow system.query_log row; or when reviewing a proposed HogQL printer change for performance. Covers extracting the ClickHouse SQL, common smells (FROM ... FINAL, JSONExtract over properties, missing skip indexes, self-joins, CTE blow-up), measuring against a real cluster, and applying the fix at the right layer (printer, query runner, or migration). Does NOT cover Postgres / Django ORM / app-database queries; for those use profiling-slow-api-endpoints.
setting-up-support-slack-locally
by PostHog
Connect a real Slack workspace to local PostHog Conversations (the SupportHog Slack app) so Slack messages become support tickets and replies post back. Use when the user wants to test the conversations Slack integration locally, hits "Support Slack OAuth client ID is not configured", gets a white screen or "Network error" on the OAuth callback, or asks how to set SUPPORT_SLACK_APP_CLIENT_ID / a tunnel for supporthog Slack events. Covers the Slack app + scopes, the SUPPORT_SLACK_* dynamic settings, and the key split: localhost for OAuth and the UI, a public tunnel only for inbound events.
warehouse-source-new-version
by PostHog
Add support for a new vendor API version to an existing Data warehouse import source, or deprecate an old one. Use when a vendor ships a new API version (Stripe date versions, Shopify quarterly versions, header-pinned revisions, /vN/ URL bumps), when implementing a version-update or deprecation task for a source under products/warehouse_sources/backend/temporal/data_imports/sources, or when repinning an ExternalDataSource to a different version. Covers deciding whether a newly announced version needs supporting at all, version declaration, dispatch, pinning semantics, deprecation metadata, and migration scripts.
fixing-flaky-tests
by PostHog
Guides an agent through reproducing, root-causing, fixing, and validating flaky tests in the PostHog monorepo. Use when a test fails intermittently in CI but passes on rerun or locally, when hogli ci:insights or the debugging-ci-failures skill classifies a failure as a flaky test, when given a GitHub Actions URL for a flaky job, when asked to check Trunk Flaky Tests for a test, PR, or master, or when asked to deflake, stabilize, or fix a flaky Jest, pytest, or Playwright test. Core discipline: reproduce locally before changing anything, fix the root cause (never mask it with sleeps, retries, or bigger timeouts), and prove the fix with an N-run validation loop sized to the observed failure rate. Stabilizing is not the only valid outcome — the skill also gates whether the test should exist, so deleting a test that catches nothing real, or re-leveling one that flakes because of the level it runs at, are first-class endings.
adding-personhog-rpc
by PostHog
Guide for adding a new RPC to personhog-replica and personhog-router. Covers eligibility checks, proto definition, code generation for Python and Node.js clients, Rust implementation (storage trait, postgres queries, service handler, router wiring), and index compatibility validation. Use when adding a new gRPC endpoint to personhog, migrating a Django ORM query to personhog, or extending the personhog service API.
setting-up-devbox
by PostHog
Starts, connects to, and troubleshoots a PostHog devbox, a remote Coder workspace for PostHog development that can also run the full stack, through hogli devbox:* commands. Use when asked to spin up or resume a devbox, open a shell or editor on it, run a command on it, mirror a local checkout to it (devbox:sync), run the PostHog app on it and share a link, clone, update, share, or free disk on a devbox, store gh or Claude Code tokens for it, or diagnose a failing devbox command (tailnet, DNS, Coder CLI version, SSH). Not for running the stack on the local machine or for changing the Coder template in posthog-cloud-infra.
using-redis-token-buckets
by PostHog
'Use when adding a bucket-like rate limit backed by Redis: a per-caller budget with burst capacity and continuous refill, a refund path for requests that did no work, or a limit whose Retry-After must be a real wait rather than a window edge. posthog/token_bucket.py provides an atomic Lua token bucket (consume, refund, peek) over posthog.redis.get_client(). Choose it over DRF SimpleRateThrottle/fixed-window cache counters when boundary bursts, top-of-window lockouts, or charge-then-refund semantics matter. Trigger terms: token bucket, rate limit, burst, refill, quota, Retry-After, fixed window, throttle.'
analyzing-experiment-query-performance
by PostHog
Pull and interpret production experiment query-performance data from the staff-only /api/debug_ch_queries endpoints backing the /experiments/staff scene: slowest experiment queries, precompute read/build health, and preaggregation cache footprint. Covers prod-US and prod-EU via a query_performance:read personal API key, all query params, and response field semantics (exception codes, exposure paths, precompute skip reasons, job states). Use when investigating slow or failing experiment queries, precompute regressions, 307/159/241 errors, preaggregation table growth, or when asked how experiment query performance or the precompute rollout is doing in production.
adding-product-alerting
by PostHog
Recommended repo-engineering guide when adding alerting to a PostHog product or extending the shared alerts platform. Routes lifecycle state machines, AlertPolicy, destinations, HogFunction dispatch, email, fixed-cadence and calendar scheduling, insight evaluation, the AlertWizard, and shared alert editor components. Use for product alert implementations, shared destination types, lifecycle or scheduling options, advanced alert settings, and platform alert infrastructure. Not for configuring alerts in an existing product.
modifying-taxonomic-filter
by PostHog
Guides safe changes to the TaxonomicFilter, PostHog's picker for events, actions, properties, cohorts, and more. Use when adding features, fixing bugs, improving search or loading performance, or refactoring the classic picker, rebuild menu, or headless filter panel. Covers real selection behavior, two live surfaces, shared telemetry, the conditional Postgres search plan, and result reveal rules.