Skip to content
Data
Skill

/domain-product

Product analytics rules: calendar spine cross-joins, date boundary caps, event type pivoting, first-run NULL behavior.

BOOST
From plugin
signalpilot
48728 skills2 agents
Install
$ npx -y skills add signalpilot-labs/signalpilot --skill domain-product --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/domain-product

Context preview

The summary Claude sees to decide when to auto-load this skill.

Product analytics rules: calendar spine cross-joins, date boundary caps, event type pivoting, first-run NULL behavior.

SKILL.md

domain-product.SKILL.md
name: domain-product
description: "Product analytics rules: calendar spine cross-joins, date boundary caps, event type pivoting, first-run NULL behavior."

Product Analytics

Driving Table

When aggregating usage or event metrics, drive FROM the fact/event table (events, sessions, pageviews), not the dimension table (users, features, pages). Users with zero activity MUST NOT appear in activity reports - they have no data to aggregate.

Calendar Spine Cross-Joins

Daily metrics models that cross-join a calendar spine with entities (users, features, pages) MUST cap the join at `current_date` - generating rows beyond today produces phantom future rows with zero metrics that inflate row counts.

If the YML description says "from creation date to current date," add `AND spine.date_day >= entity.created_at::date AND spine.date_day <= current_date` to the join condition - both bounds are required.

NEVER cross-join without a date cap - unbounded spines grow indefinitely and break row count expectations.

When an entity has a `created_at` or equivalent timestamp, the spine MUST start from that date, not from the earliest date in the spine - starting earlier produces rows before the entity existed.

Event Type Pivoting

When an events table has a `type` or `event_name` column, pivot distinct values into separate metric columns - each event type becomes a `count_<type>` column in the output.

Do NOT filter the events table to a single type before pivoting - all types must appear in the output as separate columns, using conditional aggregation (`COUNT(CASE WHEN type = 'x' THEN 1 END)`).

Read the YML or a sibling model to confirm the exact set of event types expected - inventing column names from partial data causes schema mismatches.

First-Run Behavior

On first build with no prior state, rolling window columns (7-day avg, 30-day sum) MUST be NULL for the first N-1 periods - this is correct behavior, not a bug.

Do NOT substitute 0 for NULL in rolling window columns - NULL means "insufficient history," 0 means "activity was zero."

Period-over-period columns follow the same rule: NULL on first build. See dbt-workflow "Incremental Models and Period-Over-Period Columns" for the full rule.

Read more
Ships withsignalpilot
Get the whole plugin
Stats
487
Stars
27
Forks
Active
Maintenance
Python
Language
Apache-2.0
License
17d ago
Last commit
6mo ago
Created
4h ago
Added

Repo: signalpilot-labs/signalpilot

Other skills on signalpilot.