RUM Tracking
Guides product-analytics and RUM event tracking for web (React/Next.js) and mobile (React Native/Expo) apps. Decides what to capture, what to drop, what's PII, and how to add, audit, update, and remove tracking code without breaking downstream dashboards.
External dependency. The OTel guidance in
rules/otel-conventions.mdbuilds on theotel-instrumentationandotel-semantic-conventionsskills, which live in the dash0 agent-skills repo, not this one. That rule invokes them at runtime viaSkill()when they're installed (and skips silently otherwise) — install them alongside this skill to get their authoritative span/metric/attribute guidance.
This
SKILL.mdis a thin index. Detailed rules live inrules/*.mdand load on demand. Worked examples live inreferences/*.md. Literal scaffolding lives intemplates/*.md.
Mode Detection
Parse $1 as the mode.
State the detected mode in one line before continuing.
| Mode | Default | Trigger |
|---|---|---|
guide |
yes | "what should I track", "is this worth tracking", default if no mode |
implement |
"add tracking", "instrument this", "track this event" | |
audit |
"audit tracking", "review analytics", "find tracking issues" | |
remove |
"remove tracking", "delete this event", "deprecate", "/rm-tracking" | |
plan |
"tracking plan", "design event schema", "what events do we need" |
If $1 is a target file or directory, treat it as the scope for audit,
implement, or remove.
Workflow by Mode
Guide mode (default)
The user is deciding whether and what to track at a specific point.
- Load
rules/what-to-track.mdandrules/what-not-to-track.md. - Cross-check the proposal against
rules/pii-and-compliance.md. - Recommend an event name + property set using
rules/event-design.md. - If the project uses OpenTelemetry RUM (Dash0 SDK Web, OTel browser /
mobile, Embrace), also apply
rules/otel-conventions.md. - Surface canonical events from
references/event-catalog.mdinstead of inventing new ones when one fits.
Implement mode
The user wants tracking code written.
- Confirm the event is in the tracking plan
(
rules/tracking-plan.md). If not, propose adding it to the plan first and gate the user before writing instrumentation. - Pick the platform:
- Web (React/Next.js) →
rules/implementation-web.md. - Mobile (React Native/Expo) →
rules/implementation-mobile.md.
- Web (React/Next.js) →
- If using OpenTelemetry, also load
rules/otel-conventions.md. - All tracking calls must go through the centralized wrapper
(
templates/analytics-wrapper.template.ts). Never call the vendor SDK directly from a component. - Run the PII gate from
rules/pii-and-compliance.mdon every property before the diff is final.
Audit mode
The user wants existing tracking reviewed.
- Walk the checklist in
rules/audit-checklist.md. - For every finding, cite a file path and line number.
- Group findings into: blocking (PII / consent / compliance), important (drift / ghost events / cardinality), nice-to-have (naming consistency).
- Output a ranked fix list — do not auto-edit unless the user approved a pre-defined audit scope.
Remove mode
The user wants tracking deprecated or deleted.
- Apply the lifecycle in
rules/update-and-remove.md. - Find every callsite via the centralized wrapper's typed event names.
- Identify downstream consumers (dashboards, funnels, dbt models, cohorts) before deletion.
- Mark
deprecatedfirst, set a sunset date, then remove. - Update the tracking plan and the inventory in the same PR.
Plan mode
The user wants to design, update, or codegen a tracking plan.
- Apply the structure in
rules/tracking-plan.md. - Start from
templates/tracking-plan.template.yaml. - Choose a naming school (
rules/event-design.md) and freeze it for the project. - Wire codegen (Avo, RudderTyper, Typewriter, or hand-rolled
json-schema-to-typescript) so the wrapper is type-checked.
Required Reading by Mode
Load on demand — do not preload.
references/platforms.md is optional — load
when the user asks "which platform should we use" or names a specific
vendor.
Core Principles
- The tracking plan is the source of truth. Every event must exist in the plan before it exists in code.
- Centralized wrapper, never raw SDK calls.
One module owns every
track()callsite; swapping vendors must be a single-file change. - Type-safe events. Use codegen (Avo, RudderTyper, Typewriter) or a hand-rolled discriminated union so renames break the build.
- PII never appears in event properties.
Use opaque
user.id, hash for correlation, strip URLs and free-text. - Low-cardinality event names; rich, bounded properties. ≤ 30 event names in a typical app; high-value context in properties.
- Defer sampling to the pipeline. SDKs export everything; the Collector or platform decides what to keep.
- OpenTelemetry semantic conventions when present.
user.id,session.id,browser.*,app.*,error.typecome from the registry — do not invent custom names that overlap. - Remove tracking the same way you add it. Plan first, deprecate, find consumers, then delete.
Anti-patterns (one-liners)
- Scattering
posthog.capture()/mixpanel.track()calls across components instead of one wrapper. - Tracking every hover, scroll, or render — drowns signal, explodes cost.
- Putting email, full URLs with tokens, raw
req.body, or stack traces with user input into event properties. - Using email or username as
distinct_id/user.id— always opaque. - Naming events inconsistently (
signupanduser_registeredfor the same concept). - Deleting an event before checking which dashboards consume it.
- Configuring SDK-side sampling — sample in the Collector instead.
- Treating hashed email as anonymous — it remains personal data under GDPR.
Definition of Done
- Mode detected and stated.
- Required reading for the mode loaded.
- If
implementorremove: tracking plan updated in the same diff. - PII gate run on every new or modified event.
- Centralized wrapper used; no raw SDK calls in feature code.
- Downstream consumers identified before removal.
- Recommendation cites file paths and line numbers, or proposes a concrete diff.