| name | identify-employees |
| description | Detect whether the configured customer's tracker tags employee/internal pageviews via `extra_data`, and if so, save the filter so reports exclude that traffic. Use when the user asks to identify employees, exclude employee traffic, filter internal users, or says results look skewed by their own staff. |
Identify employee traffic
Some Parse.ly customers tag their employees' pageviews in the tracker via extra_data (e.g., extra_data['Internal'] = true set on logged-in users). Parse.ly's dashboard uses that tag for segment filtering, but the DPL stream is raw – tagged events still arrive. This flow finds that tag (when present and unambiguous) and saves it to bucket.json. Subsequent staircase runs apply the filter automatically and surface a one-line note in the report.
Customers who use Parse.ly's account-level IP blocklist instead (the more common pattern) need nothing from this flow – their DPL events are already filtered upstream.
The user may ask to clear the saved filter instead of detecting one (e.g. "remove the employee filter", or the --clear argument on harnesses with slash commands).
Output discipline
Terse. The detection script prints its own one-line result; output it verbatim and stop.
Steps
-
Resolve the plugin root. Every bash snippet below assumes $plugin_root is set in that shell invocation; re-run this line whenever you start a new shell:
plugin_root="${CLAUDE_PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-<plugin-root>}}"
plugin_python="${AGENTIC_ANALYTICS_VENV:-${AGENTIC_ANALYTICS_DATA_DIR:-$HOME/.local/share/agentic-analytics}/venv}/bin/python"
[ -x "$plugin_python" ] || plugin_python="python3"
<plugin-root> is the plugin's install directory – the directory two levels above this SKILL.md file. In a dev checkout of the source repo that's plugin/. $plugin_python is the plugin's isolated venv (created by the init flow at $AGENTIC_ANALYTICS_DATA_DIR/venv, default ~/.local/share/agentic-analytics/venv); it falls back to python3 if the venv doesn't exist yet.
-
Load bucket config. Read ${XDG_CONFIG_HOME:-~/.config}/agentic-analytics/bucket.json. It contains:
bucket – S3 bucket holding the customer's DPL events.
cache_dir – a slug identifying the customer's data (e.g. acme).
If the file is missing, tell the user to run the init flow first (/agentic-analytics:init on harnesses with slash commands, or "set up agentic analytics" in chat) and stop.
-
Handle a clear request. If the user asked to clear, remove any saved filter and stop:
"$plugin_python" "$plugin_root/skills/identify-employees/scripts/detect_employee_filter.py" \
--bucket-config "${XDG_CONFIG_HOME:-$HOME/.config}/agentic-analytics/bucket.json" \
--clear
Output the script's one-line result and stop.
-
Run detection. Otherwise sample events from the catalog and write any unambiguous filter to bucket.json. Pass --site <site> to scope the sample to a specific site (when the user provides one – via a slash-command argument on harnesses that have them, or in chat); omit it to sample across all sites:
"$plugin_python" "$plugin_root/skills/identify-employees/scripts/detect_employee_filter.py" \
--bucket-config "${XDG_CONFIG_HOME:-$HOME/.config}/agentic-analytics/bucket.json" \
[--site <site>]
-
Output the script's one-line result verbatim. Three possibilities:
- Match found: "Detected employee traffic tagged with
extra_data['<key>'] = <value> (X% of N sampled pageviews). Will filter this out of audience reports so it doesn't skew your results. Tell me if this is incorrect."
- No match: "No unambiguous employee-traffic tag detected in N sampled pageviews. No filter applied."
- Lake empty: "No pageview events found in the lake[ for site '']. Run /agentic-analytics:staircase or /agentic-analytics:refresh-cache first." – tell the user to run the staircase report or the refresh-cache flow first to populate the lake, then re-run this flow.
Don't add framing or summary.
Notes
- The filter is auto-applied only when unambiguous (matched case-insensitively): known key name in
internal, is_internal, is_employee, employee, staff, internal_user/internalUser, internal_traffic; boolean-ish value (true/1/yes); and tagged share between 0.1% and 25% of sampled pageviews. Ambiguous setups (multiple distinct values on the same key, or a share outside that range) are silently skipped.
- Re-running this flow after the customer changes their tracker is the right way to refresh the detected filter.
- A clear request removes any saved filter and exits without scanning – useful when detection got the wrong key and you want to start over.
- This flow does not touch Parse.ly's per-account IP blocklist, which is the canonical mechanism for customers who go that route (managed by Parse.ly Support, applied upstream of the DPL).