Product & Data Analytics
Scope: product/business events & funnels. System health/SLOs → .claude/skills/observability/SKILL.md; relevance → .claude/skills/search/SKILL.md.
When to use
- Designing an event taxonomy and tracking plan for a new product or feature.
- Integrating a client-side or server-side analytics SDK (Segment, Amplitude, Mixpanel, PostHog, RudderStack, GA4, Heap).
- Building or auditing a data warehouse pipeline: raw events → warehouse (BigQuery, Snowflake, Redshift, ClickHouse) → dbt models → BI dashboards.
- Implementing consent management and privacy-safe tracking (GDPR, CCPA, COPPA).
- Designing A/B or multivariate experimentation infrastructure (feature flags, assignment, analysis).
- Building product dashboards, funnels, retention curves, or cohort analyses.
- Auditing tracking coverage: finding gaps where events are missing or definitions are inconsistent.
- Migrating from one analytics provider to another.
Applies to web apps, mobile apps (iOS/Android/React Native/Flutter), backend APIs, AI/agent products, games, and data platforms.
Workflow
Phase 1 — Define Before You Instrument
1. Start with business questions, not events.
Analytics serve decisions. Before defining a single event, list the top 10 business questions the team needs to answer in the next quarter. Examples: "What percentage of sign-ups complete onboarding?", "Which feature correlates with 90-day retention?", "What is the conversion rate from free to paid by acquisition channel?". The event taxonomy exists to answer these questions — not to log everything and figure it out later.
2. Design the event taxonomy.
Use a consistent naming convention across the entire product. The most widely adopted pattern:
<noun>_<verb> (snake_case)
object → what was acted on
action → what happened (past tense)
Examples:
user_signed_up
onboarding_step_completed
feature_enabled
checkout_started
payment_succeeded
subscription_cancelled
search_performed
experiment_assigned
Document every event in a tracking plan (see Output format). Each event entry specifies: event name, trigger description (when it fires), properties (name, type, required/optional, example value), platforms (web/iOS/Android/server), owner (team/squad).
3. Define a standard property schema.
Every event carries a base set of properties automatically (via the SDK or middleware):
# Identity
anonymous_id string pre-auth session identifier
user_id string post-auth stable identifier (internal ID, not email)
# Session / context
session_id string
timestamp ISO-8601 UTC
timezone string (IANA)
locale string (BCP-47)
# Platform
platform web | ios | android | server
app_version string (semver)
os_version string
browser string (web only)
# Acquisition
utm_source string
utm_medium string
utm_campaign string
referrer string
# Experiment
active_experiments array<{experiment_id, variant}>
Custom events then add their own properties on top of this base. Never put PII (email, name, phone) in event properties unless it is a deliberate, consent-gated action (e.g., identify call for CRM sync). Use internal IDs everywhere.
4. Identify PII risks and design the consent layer.
Map every event property to a PII classification: non-PII, pseudonymous (user_id), or PII (email, name, IP). IP address is PII under GDPR. For EU/UK users, you need consent before firing analytics events to third-party tools. Design this before instrumentation starts:
- Implement a Consent Management Platform (CMP) or use the SDK's built-in consent controls (Segment Consent Manager, PostHog's cookieless mode, GA4 consent mode).
- Server-side tracking reduces browser-level PII exposure and is more resilient to ad blockers.
- If targeting users under 13 (COPPA) or under 16 (GDPR child provisions), analytics must be strictly necessary only.
Phase 2 — Instrument
5. Choose the instrumentation layer: client-side, server-side, or hybrid.
| Layer |
Use when |
Pros |
Cons |
| Client-side SDK |
Behavioral events (clicks, scroll, form interactions), attribution, session replay |
Rich context, low latency |
Blocked by ad blockers, PII leakage risk, harder to enforce schema |
| Server-side API |
Business events (payment succeeded, account created, subscription changed) |
Authoritative, no blockers, enforces schema |
No client context (browser, referrer) unless forwarded |
| Hybrid |
Most production systems |
Best of both |
Two code paths to maintain |
Use Segment or RudderStack as the Customer Data Platform (CDP) to route one stream of events to multiple destinations (warehouse, Amplitude, Intercom, CRM) rather than adding multiple SDKs.
6. Implement tracking plan enforcement.
Schema drift kills data quality. Enforce it:
- Use TypeScript types or a JSON Schema for each event, generated from the tracking plan. Use Segment Protocols, RudderStack Data Catalog, or Amplitude Data to enforce schemas at ingestion.
- In CI: add a lint step that validates any new
analytics.track() call against the tracking plan definition. Reject events with unknown names or missing required properties.
- In production: log schema violations to a dead-letter queue; alert on spike in violations.
7. Instrument using the identify → group → track → page/screen pattern.
// On auth:
analytics.identify(userId, { plan: 'pro', created_at: '...' })
// On org-level context (B2B):
analytics.group(orgId, { name: 'Acme Corp', employee_count: 500 })
// On every meaningful action:
analytics.track('checkout_started', {
cart_value_cents: 4999,
item_count: 3,
currency: 'USD'
})
// On page/screen views (web/mobile):
analytics.page('Checkout', { step: 'address' })
Use server-side identify and track for business events to prevent client-side tampering. The server is the source of truth for conversion and revenue events.
Examples shown in JS/Node; the same patterns apply across platforms — equivalents (mobile, Go, Python, etc.) follow the Standards table.
Phase 3 — Warehouse Pipeline
8. Design the raw → modeled → serving layer architecture.
Raw events (immutable, append-only)
└── Segment/RudderStack → warehouse raw schema
e.g. bigquery.segment_raw.tracks, .pages, .identifies
Staging models (dbt, clean & typed)
└── stg_users.sql, stg_events.sql, stg_sessions.sql
Mart models (business-oriented)
└── fct_events.sql → one row per event
└── fct_sessions.sql → sessionized events
└── dim_users.sql → user attributes at snapshot
└── fct_funnel_steps.sql → funnel analysis
└── fct_retention_cohorts.sql
BI layer (Looker, Metabase, Superset, Mode)
└── reads from mart models only
Preserve raw events immutably. Never transform in place. dbt transforms are deterministic and re-runnable — if a business logic rule changes, re-run the model rather than patching raw data.
9. Define sessions and identity stitching.
Sessions: group events by anonymous_id with a 30-minute inactivity timeout (configurable). This requires a sessionization SQL window function in dbt. Sessions that cross auth boundaries (anonymous → identified) must be merged so the full journey is visible.
Identity stitching: when a user signs up, alias their anonymous_id to user_id. Record this alias event. Your warehouse model must propagate the user_id back to pre-signup events for that anonymous_id. Without this, sign-up conversion is systematically undercounted.
10. Implement dbt models with tests.
Every dbt model must have:
# schema.yml
models:
- name: fct_events
columns:
- name: event_id
tests: [unique, not_null]
- name: user_id
tests: [not_null]
- name: event_name
tests: [not_null, accepted_values: {values: [...]}]
- name: event_timestamp
tests: [not_null]
Run dbt test in CI. A failing uniqueness test on event_id indicates duplicate event delivery — fix the deduplication logic, not the test.
Phase 4 — Experimentation
11. Design the experiment assignment layer.
Experiments require: assignment (which variant?), exposure logging (when was the user first assigned?), and analysis (did the variant move the metric?).
- Use a feature flag + experimentation platform: PostHog, LaunchDarkly, Statsig, Optimizely, GrowthBook (open source), or a homegrown feature flag service.
- Assign variants server-side for consistency across platforms and to prevent variant leakage.
- Log an
experiment_assigned event at first exposure with {experiment_id, variant, assignment_method}.
- Enforce one experiment assignment per user per experiment (sticky assignment). If the user's bucket changes mid-experiment, the data is polluted.
- Define the metric (primary + guardrail) and minimum detectable effect before launching the experiment. Use a sample size calculator (
statsig.com/calculator, or scipy.stats.norm).
12. Run analysis correctly.
- Use the exposure event (not the page view or sign-up) as the experiment entry point. Analyzing users who were never exposed is a common bias.
- Use two-sample t-test (continuous metrics) or z-test for proportions (conversion metrics). Apply Bonferroni correction if testing multiple metrics.
- Do not peek at results and stop early when p < 0.05 — this inflates false positives. Use sequential testing (CUPED, mSPRT) if you need early stopping guarantees.
- Run experiments for at least one full business cycle (typically 2 weeks) to avoid day-of-week effects.
Standards
Do:
- Define the tracking plan in a versioned document before writing any instrumentation code. Treat it like a schema migration.
- Use server-side events for all business-critical conversions (payment, sign-up, subscription). Client-side events are supplementary.
- Enforce the event schema in CI and at ingestion time. Reject or quarantine events that fail validation.
- Store raw events immutably. Model in dbt; never transform raw tables.
- Use internal user IDs in events, never email addresses. Resolve to PII only in controlled, consented contexts.
- Version your dbt models and run
dbt test in CI.
- Document every metric definition: numerator, denominator, filter, time window. "DAU" is ambiguous without this.
- Set data retention policies: raw events 12–24 months hot, archive thereafter. PII-bearing tables have shorter retention + right-to-erasure procedures.
Do not:
- Put PII (email, phone, full name, IP) in general event properties without explicit consent and a documented retention policy.
- Instrument without a tracking plan — "log everything and figure it out later" produces unmaintainable, contradictory data.
- Create events named
button_clicked without a noun — checkout_button_clicked vs nav_menu_button_clicked are different events with different semantics.
- Add high-cardinality identifiers (order IDs, session UUIDs) as properties on high-volume events if the warehouse bill is a concern — use them on low-volume business events only. (For metric-label cardinality in time-series backends, observability owns the guidance: see
.claude/skills/observability/SKILL.md.)
- Mutate or delete raw event records. Corrections belong in a correction table or a dbt
is_valid flag.
- Share A/B test results before the experiment has reached statistical significance and the pre-defined minimum sample size.
- Run multiple experiments on the same user population concurrently without interaction analysis.
Common mistakes to avoid
- Identity fragmentation: desktop anonymous_id, mobile anonymous_id, and user_id all treated as separate users. Fix: alias calls at sign-up; warehouse-level identity stitching.
- Conversion undercounting: counting sign-ups only for users who triggered the server-side event, missing users whose request failed after payment. Fix: log
payment_succeeded after confirmation, not after client redirect.
- Schema drift accumulation: property names change across releases (
user_plan → subscription_tier → plan_name). Fix: breaking changes in the tracking plan require a migration ticket and a dbt model update on the same day.
- Experiment novelty effect: testing a new UI element sees an inflated conversion in week 1 due to novelty. Fix: run experiments for at least 2 full business cycles; check for novelty decay in daily breakdown.
- Self-selection bias in cohort analysis: comparing users who adopted feature X to those who didn't — adopters are inherently more engaged. Fix: use experiment assignment as the causal mechanism, not feature adoption.
- Warehouse cost explosion: loading raw events into BigQuery with scan-based pricing and running queries on the full history. Fix: partition on
event_timestamp; cluster on event_name; require partition filters in queries.
- Missing funnel denominators: reporting "20% of users completed step 3" when the denominator was anyone who ever visited the page, not users who entered the funnel at step 1. Fix: anchor every funnel to a clearly defined entry event.
Output format
Primary deliverables:
- Tracking plan:
docs/specs/tracking-plan.md — event taxonomy table (event name, trigger, properties, platform, owner), identity strategy, consent layer design, SDK/CDP choice.
- Data model spec:
docs/specs/analytics-data-model.md — warehouse schema layers (raw, staging, mart), dbt model graph, retention policy, identity stitching logic.
- Experimentation runbook:
docs/runbooks/experimentation.md (use .claude/templates/runbook.md) — how to create, launch, analyze, and close an experiment; statistical requirements.
Supporting artifacts (in project source):
- Tracking plan enforcement schema (JSON Schema or TypeScript types per event).
- Analytics middleware / wrapper module with base properties injected.
- dbt
schema.yml with tests for each mart model.
- dbt staging and mart model SQL.
- CI lint step for tracking plan compliance.
- Consent gate implementation (CMP integration or SDK consent controls).
Related checklists
.claude/checklists/privacy-compliance.md — consent layer, PII in events, retention policies, GDPR right-to-erasure, CCPA opt-out.
.claude/checklists/production.md — analytics pipeline health monitoring; alert on event volume drop (missing tracking).
.claude/checklists/data-model.md — warehouse schema design, partitioning, access control.
Related agents
.claude/agents/engineering/data-engineer.md — warehouse pipeline, dbt models, event ingestion.
.claude/agents/engineering/backend-engineer.md — server-side event instrumentation.
.claude/agents/quality/privacy-compliance-auditor.md — consent design, PII classification, GDPR/CCPA/COPPA review.
.claude/agents/core/product-manager.md — tracking plan ownership, metric definitions, experiment prioritization.
.claude/agents/domain/saas-domain-expert.md — SaaS-specific metrics (MRR, churn, NRR, product-qualified leads).
.claude/agents/domain/ecommerce-domain-expert.md — e-commerce funnels, cart abandonment, GMV tracking.
1---2name: analytics3description: Use for product analytics — event taxonomy/tracking plans, SDKs (Segment, Amplitude, Mixpanel, PostHog, GA4), warehouse pipelines (BigQuery, Snowflake, dbt), A/B experiments.4---56# Product & Data Analytics78**Scope: product/business events & funnels. System health/SLOs → `.claude/skills/observability/SKILL.md`; relevance → `.claude/skills/search/SKILL.md`.**910## When to use11- Designing an event taxonomy and tracking plan for a new product or feature.12- Integrating a client-side or server-side analytics SDK (Segment, Amplitude, Mixpanel, PostHog, RudderStack, GA4, Heap).13- Building or auditing a data warehouse pipeline: raw events → warehouse (BigQuery, Snowflake, Redshift, ClickHouse) → dbt models → BI dashboards.14- Implementing consent management and privacy-safe tracking (GDPR, CCPA, COPPA).15- Designing A/B or multivariate experimentation infrastructure (feature flags, assignment, analysis).16- Building product dashboards, funnels, retention curves, or cohort analyses.17- Auditing tracking coverage: finding gaps where events are missing or definitions are inconsistent.18- Migrating from one analytics provider to another.1920Applies to web apps, mobile apps (iOS/Android/React Native/Flutter), backend APIs, AI/agent products, games, and data platforms.2122---2324## Workflow2526### Phase 1 — Define Before You Instrument2728**1. Start with business questions, not events.**29Analytics serve decisions. Before defining a single event, list the top 10 business questions the team needs to answer in the next quarter. Examples: "What percentage of sign-ups complete onboarding?", "Which feature correlates with 90-day retention?", "What is the conversion rate from free to paid by acquisition channel?". The event taxonomy exists to answer these questions — not to log everything and figure it out later.3031**2. Design the event taxonomy.**32Use a consistent naming convention across the entire product. The most widely adopted pattern:3334```35<noun>_<verb> (snake_case)36 object → what was acted on37 action → what happened (past tense)3839Examples:40 user_signed_up41 onboarding_step_completed42 feature_enabled43 checkout_started44 payment_succeeded45 subscription_cancelled46 search_performed47 experiment_assigned48```4950Document every event in a **tracking plan** (see Output format). Each event entry specifies: event name, trigger description (when it fires), properties (name, type, required/optional, example value), platforms (web/iOS/Android/server), owner (team/squad).5152**3. Define a standard property schema.**53Every event carries a base set of properties automatically (via the SDK or middleware):5455```56# Identity57anonymous_id string pre-auth session identifier58user_id string post-auth stable identifier (internal ID, not email)5960# Session / context61session_id string62timestamp ISO-8601 UTC63timezone string (IANA)64locale string (BCP-47)6566# Platform67platform web | ios | android | server68app_version string (semver)69os_version string70browser string (web only)7172# Acquisition73utm_source string74utm_medium string75utm_campaign string76referrer string7778# Experiment79active_experiments array<{experiment_id, variant}>80```8182Custom events then add their own properties on top of this base. Never put PII (email, name, phone) in event properties unless it is a deliberate, consent-gated action (e.g., identify call for CRM sync). Use internal IDs everywhere.8384**4. Identify PII risks and design the consent layer.**85Map every event property to a PII classification: non-PII, pseudonymous (user_id), or PII (email, name, IP). IP address is PII under GDPR. For EU/UK users, you need consent before firing analytics events to third-party tools. Design this before instrumentation starts:86- Implement a Consent Management Platform (CMP) or use the SDK's built-in consent controls (Segment Consent Manager, PostHog's cookieless mode, GA4 consent mode).87- Server-side tracking reduces browser-level PII exposure and is more resilient to ad blockers.88- If targeting users under 13 (COPPA) or under 16 (GDPR child provisions), analytics must be strictly necessary only.8990---9192### Phase 2 — Instrument9394**5. Choose the instrumentation layer: client-side, server-side, or hybrid.**9596| Layer | Use when | Pros | Cons |97|-------|----------|------|------|98| Client-side SDK | Behavioral events (clicks, scroll, form interactions), attribution, session replay | Rich context, low latency | Blocked by ad blockers, PII leakage risk, harder to enforce schema |99| Server-side API | Business events (payment succeeded, account created, subscription changed) | Authoritative, no blockers, enforces schema | No client context (browser, referrer) unless forwarded |100| Hybrid | Most production systems | Best of both | Two code paths to maintain |101102Use Segment or RudderStack as the Customer Data Platform (CDP) to route one stream of events to multiple destinations (warehouse, Amplitude, Intercom, CRM) rather than adding multiple SDKs.103104**6. Implement tracking plan enforcement.**105Schema drift kills data quality. Enforce it:106- Use TypeScript types or a JSON Schema for each event, generated from the tracking plan. Use Segment Protocols, RudderStack Data Catalog, or Amplitude Data to enforce schemas at ingestion.107- In CI: add a lint step that validates any new `analytics.track()` call against the tracking plan definition. Reject events with unknown names or missing required properties.108- In production: log schema violations to a dead-letter queue; alert on spike in violations.109110**7. Instrument using the identify → group → track → page/screen pattern.**111```112// On auth:113analytics.identify(userId, { plan: 'pro', created_at: '...' })114115// On org-level context (B2B):116analytics.group(orgId, { name: 'Acme Corp', employee_count: 500 })117118// On every meaningful action:119analytics.track('checkout_started', {120 cart_value_cents: 4999,121 item_count: 3,122 currency: 'USD'123})124125// On page/screen views (web/mobile):126analytics.page('Checkout', { step: 'address' })127```128129Use server-side `identify` and `track` for business events to prevent client-side tampering. The server is the source of truth for conversion and revenue events.130131Examples shown in JS/Node; the same patterns apply across platforms — equivalents (mobile, Go, Python, etc.) follow the Standards table.132133---134135### Phase 3 — Warehouse Pipeline136137**8. Design the raw → modeled → serving layer architecture.**138```139Raw events (immutable, append-only)140 └── Segment/RudderStack → warehouse raw schema141 e.g. bigquery.segment_raw.tracks, .pages, .identifies142143Staging models (dbt, clean & typed)144 └── stg_users.sql, stg_events.sql, stg_sessions.sql145146Mart models (business-oriented)147 └── fct_events.sql → one row per event148 └── fct_sessions.sql → sessionized events149 └── dim_users.sql → user attributes at snapshot150 └── fct_funnel_steps.sql → funnel analysis151 └── fct_retention_cohorts.sql152153BI layer (Looker, Metabase, Superset, Mode)154 └── reads from mart models only155```156157Preserve raw events immutably. Never transform in place. dbt transforms are deterministic and re-runnable — if a business logic rule changes, re-run the model rather than patching raw data.158159**9. Define sessions and identity stitching.**160Sessions: group events by `anonymous_id` with a 30-minute inactivity timeout (configurable). This requires a sessionization SQL window function in dbt. Sessions that cross auth boundaries (anonymous → identified) must be merged so the full journey is visible.161162Identity stitching: when a user signs up, alias their `anonymous_id` to `user_id`. Record this alias event. Your warehouse model must propagate the `user_id` back to pre-signup events for that `anonymous_id`. Without this, sign-up conversion is systematically undercounted.163164**10. Implement dbt models with tests.**165Every dbt model must have:166```yaml167# schema.yml168models:169 - name: fct_events170 columns:171 - name: event_id172 tests: [unique, not_null]173 - name: user_id174 tests: [not_null]175 - name: event_name176 tests: [not_null, accepted_values: {values: [...]}]177 - name: event_timestamp178 tests: [not_null]179```180181Run `dbt test` in CI. A failing uniqueness test on `event_id` indicates duplicate event delivery — fix the deduplication logic, not the test.182183---184185### Phase 4 — Experimentation186187**11. Design the experiment assignment layer.**188Experiments require: assignment (which variant?), exposure logging (when was the user first assigned?), and analysis (did the variant move the metric?).189190- Use a feature flag + experimentation platform: PostHog, LaunchDarkly, Statsig, Optimizely, GrowthBook (open source), or a homegrown feature flag service.191- Assign variants server-side for consistency across platforms and to prevent variant leakage.192- Log an `experiment_assigned` event at first exposure with `{experiment_id, variant, assignment_method}`.193- Enforce one experiment assignment per user per experiment (sticky assignment). If the user's bucket changes mid-experiment, the data is polluted.194- Define the metric (primary + guardrail) and minimum detectable effect **before** launching the experiment. Use a sample size calculator (`statsig.com/calculator`, or `scipy.stats.norm`).195196**12. Run analysis correctly.**197- Use the exposure event (not the page view or sign-up) as the experiment entry point. Analyzing users who were never exposed is a common bias.198- Use two-sample t-test (continuous metrics) or z-test for proportions (conversion metrics). Apply Bonferroni correction if testing multiple metrics.199- Do not peek at results and stop early when p < 0.05 — this inflates false positives. Use sequential testing (CUPED, mSPRT) if you need early stopping guarantees.200- Run experiments for at least one full business cycle (typically 2 weeks) to avoid day-of-week effects.201202---203204## Standards205206**Do:**207- Define the tracking plan in a versioned document before writing any instrumentation code. Treat it like a schema migration.208- Use server-side events for all business-critical conversions (payment, sign-up, subscription). Client-side events are supplementary.209- Enforce the event schema in CI and at ingestion time. Reject or quarantine events that fail validation.210- Store raw events immutably. Model in dbt; never transform raw tables.211- Use internal user IDs in events, never email addresses. Resolve to PII only in controlled, consented contexts.212- Version your dbt models and run `dbt test` in CI.213- Document every metric definition: numerator, denominator, filter, time window. "DAU" is ambiguous without this.214- Set data retention policies: raw events 12–24 months hot, archive thereafter. PII-bearing tables have shorter retention + right-to-erasure procedures.215216**Do not:**217- Put PII (email, phone, full name, IP) in general event properties without explicit consent and a documented retention policy.218- Instrument without a tracking plan — "log everything and figure it out later" produces unmaintainable, contradictory data.219- Create events named `button_clicked` without a noun — `checkout_button_clicked` vs `nav_menu_button_clicked` are different events with different semantics.220- Add high-cardinality identifiers (order IDs, session UUIDs) as properties on high-volume events if the warehouse bill is a concern — use them on low-volume business events only. (For metric-label cardinality in time-series backends, observability owns the guidance: see `.claude/skills/observability/SKILL.md`.)221- Mutate or delete raw event records. Corrections belong in a correction table or a dbt `is_valid` flag.222- Share A/B test results before the experiment has reached statistical significance and the pre-defined minimum sample size.223- Run multiple experiments on the same user population concurrently without interaction analysis.224225---226227## Common mistakes to avoid228229- **Identity fragmentation**: desktop anonymous_id, mobile anonymous_id, and user_id all treated as separate users. Fix: alias calls at sign-up; warehouse-level identity stitching.230- **Conversion undercounting**: counting sign-ups only for users who triggered the server-side event, missing users whose request failed after payment. Fix: log `payment_succeeded` after confirmation, not after client redirect.231- **Schema drift accumulation**: property names change across releases (`user_plan` → `subscription_tier` → `plan_name`). Fix: breaking changes in the tracking plan require a migration ticket and a dbt model update on the same day.232- **Experiment novelty effect**: testing a new UI element sees an inflated conversion in week 1 due to novelty. Fix: run experiments for at least 2 full business cycles; check for novelty decay in daily breakdown.233- **Self-selection bias in cohort analysis**: comparing users who adopted feature X to those who didn't — adopters are inherently more engaged. Fix: use experiment assignment as the causal mechanism, not feature adoption.234- **Warehouse cost explosion**: loading raw events into BigQuery with scan-based pricing and running queries on the full history. Fix: partition on `event_timestamp`; cluster on `event_name`; require partition filters in queries.235- **Missing funnel denominators**: reporting "20% of users completed step 3" when the denominator was anyone who ever visited the page, not users who entered the funnel at step 1. Fix: anchor every funnel to a clearly defined entry event.236237---238239## Output format240241Primary deliverables:242- **Tracking plan**: `docs/specs/tracking-plan.md` — event taxonomy table (event name, trigger, properties, platform, owner), identity strategy, consent layer design, SDK/CDP choice.243- **Data model spec**: `docs/specs/analytics-data-model.md` — warehouse schema layers (raw, staging, mart), dbt model graph, retention policy, identity stitching logic.244- **Experimentation runbook**: `docs/runbooks/experimentation.md` (use `.claude/templates/runbook.md`) — how to create, launch, analyze, and close an experiment; statistical requirements.245246Supporting artifacts (in project source):247- Tracking plan enforcement schema (JSON Schema or TypeScript types per event).248- Analytics middleware / wrapper module with base properties injected.249- dbt `schema.yml` with tests for each mart model.250- dbt staging and mart model SQL.251- CI lint step for tracking plan compliance.252- Consent gate implementation (CMP integration or SDK consent controls).253254---255256## Related checklists257- `.claude/checklists/privacy-compliance.md` — consent layer, PII in events, retention policies, GDPR right-to-erasure, CCPA opt-out.258- `.claude/checklists/production.md` — analytics pipeline health monitoring; alert on event volume drop (missing tracking).259- `.claude/checklists/data-model.md` — warehouse schema design, partitioning, access control.260261## Related agents262- `.claude/agents/engineering/data-engineer.md` — warehouse pipeline, dbt models, event ingestion.263- `.claude/agents/engineering/backend-engineer.md` — server-side event instrumentation.264- `.claude/agents/quality/privacy-compliance-auditor.md` — consent design, PII classification, GDPR/CCPA/COPPA review.265- `.claude/agents/core/product-manager.md` — tracking plan ownership, metric definitions, experiment prioritization.266- `.claude/agents/domain/saas-domain-expert.md` — SaaS-specific metrics (MRR, churn, NRR, product-qualified leads).267- `.claude/agents/domain/ecommerce-domain-expert.md` — e-commerce funnels, cart abandonment, GMV tracking.