explore-events
Profile event streams that power search, recommendations, and personalisation in a two-sided marketplace. Use when asking "what events do we have for the homefeed?", "are our impressions logging rank_position?", "does our click data have a feedback-loop bias?", "what's the schema of our conversion events?", "are anonymous sessions getting user_ids?", "what's wrong with our impression-click ordering?", or "profile the events for surface X before I build against them". Checks grain, ID stability, property completeness (rank_position, model_version, request_id, surface_id), impression-click ordering, feedback-loop bias (are impressions logged even when rank comes from the recsys itself?), and coverage gaps by side, geo, segment, or device. Flags quality issues and recommends fixes grounded in the marketplace knowledge libraries. Event-centric cousin of the data plugin's /explore-data.
What this skill does
# /marketplace:explore-events — Profile Marketplace Event Streams
> If you see unfamiliar placeholders or need to check which tools are connected, see [CONNECTORS.md](../../CONNECTORS.md).
Profile an event stream for a surface, an event name, or a specific table. Understand the shape, quality, and biases of the data **before** building anything on top of it. This is the foundation every other action command depends on.
## Usage
```
/marketplace:explore-events homefeed-impressions
/marketplace:explore-events listing_impressed
/marketplace:explore-events main.marketplace.impressions
/marketplace:explore-events search
```
## Workflow
### 1. Load Company Context
Read the `<company>-marketplace-context` skill if present — especially `events.md`, `surfaces.md`, and `gotchas.md`. Any known issues listed there are candidates to verify first.
If no context skill exists, prompt the user to run `/marketplace:bootstrap-context` first, or fall back to direct-from-stack discovery.
### 2. Resolve the Target
Parse the argument and resolve to one or more concrete event streams:
- **Surface name** (e.g., `homefeed`) → list all events that surface fires (from `surfaces.md` or discovery)
- **Event name** (e.g., `listing_impressed`) → profile that single event across all surfaces
- **Table name** (e.g., `main.marketplace.impressions`) → profile the warehouse table backing the event
If the target is ambiguous, list candidates and ask the user to pick.
### 3. Discover Schema
**If `~~product analytics` is connected:**
1. Query the tracking plan (e.g., Amplitude event schema API, Twilio Segment tracking plan) to pull declared properties
2. List declared types, required / optional, deprecation flags
**If `~~data warehouse` is connected:**
1. Describe the backing table (`DESCRIBE TABLE ...`)
2. Note schema drift vs the tracking plan
**If neither:**
Ask the user to paste a sample event or a schema description.
Present the resolved schema as a table before running any profile queries.
### 4. Profile the Stream
Run the standard profile checks, announcing each query before execution.
#### 4a. Volume and trend
```sql
SELECT
DATE(event_time) AS day,
COUNT(*) AS events,
COUNT(DISTINCT user_id) AS distinct_users,
COUNT(DISTINCT session_id) AS distinct_sessions
FROM {{table}}
WHERE event_time >= CURRENT_DATE - INTERVAL 14 DAYS
GROUP BY 1
ORDER BY 1
```
Look for: sudden drops (instrumentation break), gradual growth (healthy), spikes (incidents).
#### 4b. Property completeness
For ranked-surface events, the critical properties are `rank_position`, `model_version`, `surface_id`, `request_id`. Check coverage:
```sql
SELECT
COUNT(*) AS total,
COUNT(rank_position) * 1.0 / COUNT(*) AS rank_position_coverage,
COUNT(model_version) * 1.0 / COUNT(*) AS model_version_coverage,
COUNT(surface_id) * 1.0 / COUNT(*) AS surface_id_coverage,
COUNT(request_id) * 1.0 / COUNT(*) AS request_id_coverage,
COUNT(user_id) * 1.0 / COUNT(*) AS user_id_coverage
FROM {{table}}
WHERE event_time >= CURRENT_DATE - INTERVAL 7 DAYS
```
**Flag levels**:
- **Red** (< 90% coverage on any critical property): ranking / training / eval is compromised. Fix before any ML work.
- **Amber** (90-99%): segment-by-missing-property to understand whether the gap is systematic.
- **Green** (≥ 99%): good enough for most purposes.
#### 4c. ID stability
Check that `user_id` is stable across sessions and devices:
```sql
SELECT
session_id,
COUNT(DISTINCT user_id) AS user_ids_per_session
FROM {{table}}
WHERE event_time >= CURRENT_DATE - INTERVAL 1 DAY
GROUP BY 1
HAVING user_ids_per_session > 1
LIMIT 20
```
Sessions with > 1 `user_id` indicate cookie drift, shared devices, or logout-in-session. Flag if > 1% of sessions.
#### 4d. Impression-click ordering
Check that every click has a preceding impression in the same session:
```sql
WITH clicks_with_impression AS (
SELECT
c.*,
MAX(i.event_time) AS last_impression_time
FROM clicks c
LEFT JOIN impressions i
ON i.user_id = c.user_id
AND i.item_id = c.item_id
AND i.event_time <= c.event_time
AND i.event_time >= c.event_time - INTERVAL 30 MINUTE
WHERE c.event_time >= CURRENT_DATE - INTERVAL 1 DAY
GROUP BY c.user_id, c.item_id, c.event_time, c.session_id
)
SELECT
COUNT(*) AS total_clicks,
COUNT(last_impression_time) AS clicks_with_impression,
COUNT(*) - COUNT(last_impression_time) AS orphan_clicks
FROM clicks_with_impression
```
**Orphan clicks** (clicks without a preceding impression) are a red flag for:
- Client-side impression tracking failure (most common)
- Cross-tab navigation that breaks the join
- Bots / abuse (if the volume is very high)
#### 4e. Feedback-loop bias
**The most important check** for ranked surfaces. Are impressions logged even when the ranking came from the recsys itself?
This requires that `model_version` is populated on impressions. If it is:
```sql
SELECT
model_version,
COUNT(*) AS impressions,
AVG(rank_position) AS mean_rank,
COUNT(DISTINCT item_id) AS distinct_items
FROM impressions
WHERE event_time >= CURRENT_DATE - INTERVAL 7 DAYS
AND surface_id = '{{surface}}'
GROUP BY 1
ORDER BY impressions DESC
```
If `distinct_items` is declining over time or `mean_rank` is compressing toward 1, the model is recommending a narrowing set — a death-spiral leading indicator.
Also compute a Gini coefficient for the top-N item distribution:
```sql
WITH item_volumes AS (
SELECT
item_id,
COUNT(*) AS n
FROM impressions
WHERE event_time >= CURRENT_DATE - INTERVAL 7 DAYS
AND surface_id = '{{surface}}'
AND rank_position <= 10
GROUP BY 1
),
ranked AS (
SELECT
n,
ROW_NUMBER() OVER (ORDER BY n) AS rank,
COUNT(*) OVER () AS total_items,
SUM(n) OVER () AS total_volume
FROM item_volumes
)
SELECT
1 - 2 * SUM((total_items - rank + 1) * n) * 1.0 / (total_items * total_volume) AS gini
FROM ranked
```
Gini > 0.72 for top-10 is the death-spiral threshold per `loop-detect-death-spirals`.
#### 4f. Coverage by segment
Decompose coverage by role, geo, device, and user age:
```sql
SELECT
user_role,
geo_country,
device_type,
COUNT(*) AS events,
COUNT(rank_position) * 1.0 / COUNT(*) AS rank_coverage
FROM impressions
WHERE event_time >= CURRENT_DATE - INTERVAL 7 DAYS
GROUP BY 1, 2, 3
HAVING events > 1000
ORDER BY rank_coverage ASC
LIMIT 20
```
Segments with < 90% rank_coverage are systematic instrumentation gaps — bias risk for every downstream model.
### 5. Present Findings
Structure the output as:
```markdown
## Event Profile: {{target}}
### Schema
{{table of declared properties}}
### Volume
- 7-day average: {{n}} events / day
- Trend: {{flat | growing | declining | spiky}}
- Distinct users / day: {{n}}
### Quality
- **Critical properties**: {{red | amber | green}} per property with coverage %
- **ID stability**: {{issues found, if any}}
- **Impression-click ordering**: {{% orphan clicks}}
- **Feedback-loop signal**: {{Gini, distinct-items trend, model_version spread}}
- **Segment gaps**: {{worst segments by rank_coverage}}
### Issues
{{numbered list with severity}}
### Recommended rules
- {{rule-reference}} — {{one-line why}}
- ...
### Suggested follow-ups
- {{what /marketplace:* command to run next}}
```
### 6. Update the Context Skill
If the context skill exists, offer to update `events.md` and `gotchas.md` with the findings. Ask before writing.
## Read-only posture
Every query above is a **read** against `~~data warehouse`, `~~product analytics`, or `~~search engine`. Announce before executing. Do not propose any `INSERT`, `UPDATE`, `DELETE`, or `PutEvents`.
## Examples
### Profile a surface
```
/marketplace:explore-events homefeed
```
Profiles all events firing on the homefeed surface — impression, click, conversion — and reports quality per event.
### Profile a single event
```
/marketplace:explore-events listing_impressed
```
Profiles one event name across all surfaces.
### Profile a table
```
/marketplace:eRelated in Ads & Marketing
ads
IncludedMulti-platform paid advertising audit and optimization skill. Analyzes Google, Meta, YouTube, LinkedIn, TikTok, Microsoft, and Apple Ads. 250+ checks with scoring, parallel agents, industry templates, and AI creative generation.
banana
IncludedAI image generation Creative Director powered by Google Gemini Nano Banana models. Use this skill for ANY request involving image creation, editing, visual asset production, or creative direction. Triggers on: generate an image, create a photo, edit this picture, design a logo, make a banner, visual for my anything, and all /banana commands. Handles text-to-image, image editing, multi-turn creative sessions, batch workflows, and brand presets.
rpg-migration-analyzer
IncludedAnalyzes legacy RPG (Report Program Generator) programs from AS/400 and IBM i systems for migration to modern Java applications. Extracts business logic from RPG III/IV/ILE source code, identifies data structures (D-specs), file operations (F-specs), program dependencies (CALLB/CALLP), and converts RPG constructs to Java equivalents. Generates migration reports, complexity estimates, and Java implementation strategies with POJO classes, JPA entities, and service methods. Use when modernizing AS/400 or IBM i legacy systems, analyzing RPG source files (.rpg, .rpgle, .RPGLE), converting RPG to Java, mapping data specifications to Java classes, planning legacy system migration, or when user mentions RPG analysis, Report Program Generator, RPG III/IV/ILE, AS/400 modernization, IBM i migration, packed decimal conversion, or mainframe application rewrite.
brand-library-architect
IncludedBuild a complete brand library for a product — visual asset render pipeline, brand documentation set (BRAND, COPY, MANIFESTO, BIOS, FAQ, GLOSSARY, TONE, PRICING), open-source convention files (README, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT), and a self-contained press kit. This skill should be used when the user asks to "build a brand library / brand kit / press kit / brand assets" for a product, "set up a brand library workflow," "create a positioning manifesto plus visual identity," or any combination of brand documentation + visual asset pipeline. Apply phase-by-phase or run end-to-end. Templates are product-agnostic and use {{TOKEN}} placeholders the skill prompts the user to fill.
writing-tech-post
IncludedAuthors engineering blog posts end-to-end: launch deep-dives, incident postmortems, architecture migrations, performance case studies, tutorials, AI/agent system writeups, security disclosures, and research-to-product translations. Picks the correct archetype, plans the abstraction ladder, enforces an evidence cadence (diagrams, benchmarks, profiles, traces, code, ablations), tunes voice against publisher house styles (Datadog, Vercel, GitHub, AWS, Meta, Cloudflare, Jane Street), and runs a pre-publish gate for narrative momentum and disclosure ethics. Use when drafting a new engineering post, restructuring a draft that feels flat, deciding which evidence form belongs where, validating that depth and product context are balanced, or preparing a postmortem, migration, or performance narrative for external publication. Do not use for API reference documentation, README authoring, marketing copy, release notes, generic SEO content, ghost-written executive thought leadership, or non-engineering long-form essays.
blog-google
IncludedGoogle API integration for blog performance: PageSpeed Insights, CrUX Core Web Vitals with 25-week history, Search Console performance, URL Inspection, Indexing API, GA4 organic traffic, NLP entity analysis for E-E-A-T, YouTube video search for embedding, and Google Ads Keyword Planner. Progressive feature availability based on credential tier (API key, OAuth/service account, GA4, Ads). Shares config with claude-seo at ~/.config/claude-seo/google-api.json. Use when user says "google data", "page speed", "core web vitals", "search console", "indexation", "GA4", "keyword research", "nlp entities", "blog performance", "youtube search", "google api setup".